1

I created a class (observer) that will perform some actions based on certain events in other classes (publishers). The observer and publishers all within one dll.

I could create another class in the assembly and require that client applications call something like BootStrapper.Configure() before using other classes; however, I'd like to avoid needing to update all the client applications at the same time.

I could create a base class for the publisher classes and call BootStrapper.Configure() from there; however, the publishers currently inherit different base classes. I'd like to avoid refactoring those classes for now.

What I would really like to do is ensure that the "observer" class is instantiated when the client application is started, or the first time any class in the dll is referenced.

What is the best way to ensure the "observer" class will be instantiated before any "publishers" publish an event?

Sample Project: https://www.box.com/s/0ihvp11kd7bfb6mqlnmc I would like to make any method in BootStapper.cs execute when LogicLibrary is loaded.

Siguza
  • 21,155
  • 6
  • 52
  • 89
tgriffin
  • 483
  • 1
  • 5
  • 13
  • What mechanism are you using to relay the event from publisher to observer? – roken Feb 04 '12 at 02:41
  • @roken - The publisher classes will define .NET events and delegates. The publisher will raise the event(s), and the subscriber will provide methods for the delegates. – tgriffin Feb 04 '12 at 02:52
  • Are you using an IOC/DI solution for creating your observer instance or are you manually hooking up the events to a classic singleton? In either case, the observer will intrinsically be instantiated before it is needed. – roken Feb 04 '12 at 03:03
  • @roken - I am not using an IOC/DI solution. See the sample project I just added. If you run that solution, no methods in BootStrapper.cs will be called. – tgriffin Feb 04 '12 at 04:03
  • I'd recommend looking at the IObserver interface and the example implementation given there. Using static classes with a bootstrapper to explicitly tie them together is not flexible and buys you very little. http://msdn.microsoft.com/en-us/library/dd783449.aspx – roken Feb 04 '12 at 04:17
  • .NET has module initializers for this, but C# doesn't. Using some kind of post-compiler or writing IL yourself might do the trick, if you'd like to go that far. Related discussion: http://stackoverflow.com/questions/1915506/module-initializers-in-c-sharp – Jordão Aug 29 '15 at 21:50

2 Answers2

1

Updated in response to the posted project

The current design in the provided solution constrains the publisher(s) to be within the assembly (since the bootstrapper is hardcoding the delegate hookup) which only adds complexity without benefit. If you had publishers outside the assembly housing the observer, your current pattern would require a bootstrapper in each assembly containing a publisher. This is simply moving lines from one place to a less obvious place and will wind up being harder to maintain.

I'd recommend looking at the IObserver interface and the example implementation given there: http://msdn.microsoft.com/en-us/library/dd783449.aspx

Previous response:

If you are simply using a classic singleton as your observer, and need to reference said singleton to hook up your events, the act of referencing the singleton will ensure its creation.

It seems unnecessary to specify that the observer must be created before any class in the DLL is referenced. You should only need to guarentee that the observer is created before any publisher will raise its event.

A better solution would be to use an IOC container to create the singleton instance of the observer and automatically hook up the event for all publishers.

roken
  • 3,946
  • 1
  • 19
  • 32
  • This is what I cannot guarantee: "the act of referencing the singleton will ensure its creation." I'd like to guarantee that the singleton is created even if no client references it. As I said, I have work-arounds, but would like to know if there is a better solution. – tgriffin Feb 04 '12 at 04:10
  • +1 - I agree, but what would be the best way to do this without adding a dependency on the IoC container library to the OP's class library? – TrueWill Feb 04 '12 at 04:12
  • The best way to do it would be to stop using the static bootstrapper concept and thus eliminate the need for an autoinitializing class. – roken Feb 04 '12 at 14:08
0

There are a few methods of going about this. One method might be to use DllMain in a C++/CLR wrapper DLL, but I'd have to give that some extra thought. I'd be more likely to call some sort of instantiation method from the static constructor of every class in the DLL to keep it fully managed.

internal static class DllMain
{
    private volatile bool Initialized = false;

    public static void OnStaticConstructor()
    {
        if (!Initialized)
        {
            Initialized = true;
            Initialize();
        }
    }

    private void Initialize()
    {
        // Put whatever you need to run once here.
    }
}

public class A
{
    static A()
    {
        DllMain.OnStaticConstructor();
    }

    // ...
}

public class B
{
    static B()
    {
        DllMain.OnStaticConstructor();
    }

    // ...
}
Zenexer
  • 18,788
  • 9
  • 71
  • 77
  • I think this is pretty close to what I was thinking with "I could create a base class for the publisher classes and call BootStrapper.Configure() from there; however, the publishers currently inherit different base classes. I'd like to avoid refactoring those classes for now." I may end up having to refactor the base classes. – tgriffin Feb 04 '12 at 04:07
  • @tgriffin It shouldn't really require that much refactoring, and it would be much easier than the alternative. – Zenexer Feb 04 '12 at 04:13