views:

20

answers:

1

The application I'm working on requires objects to be created on the fly, some of them also use singleton instances (lifetime manager based, of course), because there is state involved (think WCF service sessions, etc...).

As long as I resolve via the same instance of the UnityContainer class, everything is fine, but I think here the snake is biting into it's own tail:

a) Everyone hates the most intuitive idea of providing a single instance of the UnityContainer - class

b) At the same time this seems to be the only logical solution

I mean, seriously, if there is so much hate for the ServiceLocator - pattern, what else do you suggest then?

Edit:

Ok, I found a very good solution. The UnityContainer - class can inject itself as a singleton. Here is an example (it's written in a very ugly style, but it proves my point):

    static void Main(string[] args)
    {
        var container = new UnityContainer().LoadConfiguration();
        var test = container.Resolve<MyDependant>();
        test.TestTheDependency();

        foreach (var registration in container.Registrations)
        {
            Console.WriteLine(registration.RegisteredType.Name);
        }

        var container2 = container.Resolve<IUnityContainer>();

        Console.WriteLine(container.GetHashCode());
        Console.WriteLine(container2.GetHashCode());
        test.ShowUnityContainerHashCode();

        var testD1 = container.Resolve<ITestDependency>();
        var testD2 = container2.Resolve<ITestDependency>();

        Console.WriteLine(testD1.GetHashCode());
        Console.WriteLine(testD2.GetHashCode());
        test.ShowTestDependencyHashCode();
    }

Shows 2 blocks á 3 times the same hash code if

  <register type="ITestDependency" mapTo="TestDependency">
    <lifetime type="singleton"/>
  </register>
  <register type="MyDependant" />

is set in app.config.

Very nice. I love Unity, seriously. This is hot stuff.

+1  A: 

If you truly must share the same instance between multiple UnityContainer instances, the best solution might be to simply resolve it once and subsequently register the instance in all other UnityContainer instances:

var f = container1.Resolve<IFoo>();
// ..
container42.RegisterInstannce<IFoo>(f);
// ..

Another alternative that presents itself is to make the implementation a true Singleton, but still register the instance in every container instance. That makes it an implementation detail that there's a Singleton in play, and it removes many of the disadvantages of the Singleton pattern because consumers will never know about it.

However, the best solution is to use only a single container. Although I can think of a few, rather exotic, scenarios where an arbitrary number of container instances are appropriate, in the vast majority of cases, a single container instance is the correct configuration.

Mark Seemann