Using Unity to make Singleton-ness an implementation detail

The most common, canonical use of the Singleton pattern irritates me. Every time I see it, I think, “The singleton-ness of a class is an implementation detail, and shouldn’t leak out through that class’s interface.” Yet, that’s what it always does.

In the usual implementation, someone decides that some new class they’ve written is so resource critical, or so standalone, or so useful that they can have only one instance of that class and that instance has to be visible everywhere. Ignoring the intricacies of threading and so on, a Singleton usually looks exactly like this:

   1: public class MyImportantResource

   2: {

   3:     private static MyImportantResource instance;

   4:  

   5:     private MyImportantResource()

   6:     {

   7:         // ...

   8:     }

   9:  

  10:     public static MyImportantResource Instance()

  11:     {

  12:         if (instance == null) instance = new MyImportantResource();

  13:         return instance;

  14:     }

  15: }

And it gets used everywhere like this:

   1: public class Consumer

   2:     {

   3:         public Consumer()

   4:         {

   5:             var importantResource = MyImportantResource.Instance();

   6:             importantResource.FooTheBar();

   7:         }

   8:     }

Now what happens when I decide I want two of these? Or I decide that I want to let people create as many of these resources as possible? Or, even more commonly, what happens when I want my Consumer class to use a mocked out version of MyImportantResource? I’m scre^h^h^h^hin trouble.

The trouble comes from the fact that Consumer is reaching out into the ether and grabbing the resource it needs on its own. It isn’t giving me, the developer, control over what type of ImportantResource to use or where the ImportantResource is coming from. The Inversion of Control principle is being violated by having the class gather its own resources rather than having its creator decide and pass resources to it.

My typical solution

What I typically have been telling people is that it is OK to have a singleton, treat it as a singleton, and love the singleton pattern… within reason. At the point in your code where you’re creating all your objects and wiring them up, you should feel perfectly free to use singletons. But no layer beneath that should have any knowledge of the singleton-ness of a class. Grab that singleton and pass it into whoever needs it, preferably as an interface, and you’ve restored order and testability to your system by again returning to the Inversion of Control principle.

My DI solution

Dependency Inversion containers solve this problem for you automatically. I’ve been using Unity lately, and I’ve grown to really like it. One of the things I really like about it, and I’m sure all DI containers have this property, is that I can register a type with the container and tell it that I only want it to create a single instance of this type and pass it around whenever someone asks for that type. Bam! I have a singleton again, but I’ve completely separated the singleton-ness of the class from its singleton-like usage. Major win. Here is the code that lets me do that.

First, the interface over the important resource:

   1: public interface IImportantResource

   2: {

   3:     void FooTheBar();

   4: }

Now the changes in the MyImportantResource class to bring it back to being a regular class. Note that all mention of singleton-ness is gone from this class. Its just a plain, old class again, which is how we like it.

   1: public class MyImportantResource : IImportantResource

   2: {

   3:     public MyImportantResource()

   4:     {

   5:         // ...

   6:     }

   7:  

   8:     public void FooTheBar()

   9:     {

  10:         throw new NotImplementedException();

  11:     }

  12: }

Next, the changes in the Consumer class that promote the loose coupling encouraged by Inversion of Control, by injecting an IImportantResource at construction:

   1: public class Consumer

   2: {

   3:     public Consumer(IImportantResource importantResource)

   4:     {

   5:         importantResource.FooTheBar();

   6:     }

   7: }

And finally, the object construction code I can write:

   1: public static class Configurator

   2: {

   3:     private static IUnityContainer container;

   4:  

   5:     public static void Main(string[] args)

   6:     {

   7:         container = new UnityContainer();

   8:  

   9:         container.RegisterType<IImportantResource, MyImportantResource>(new ContainerControlledLifetimeManager());

  10:  

  11:         Consumer consumer = container.Resolve<Consumer>();

  12:     }

  13: }

The interesting bit of code here is on line 9, where I register MyImportantResource. I’m telling the container that whenever someone asks for an IImportantResource, it should give them a MyImportantResource object, and that it should give it the same instance every time (that what the new ContainerControlledLifetimeManager()) says. I’ve magically turned my MyImportantResource into a singleton class without polluting the code of that class with statics and instance methods.

Conclusion

Operationally nothing has changed. Assuming people always go to the container for their object instances, MyImportantResource is still a singleton. I will only have one instance of it, it is still accessible from a single place. Should I ever decide to allow 4 instances of it, I can create my own lifetime manager class that will create up to four instances and manage them for me. But now all of my classes are just that, classes. The design decision of how many instances of the resource is separated from the operation of the resource, which allows the two different design issues to evolve separately. And I’ve applied Dependency Inversion to the Consumer class, which allows it to have mock versions of the resource injected to enable testing scenarios that were more difficult when it was using the singleton.

– bab

This entry was posted in Uncategorized. Bookmark the permalink.

2 Responses to Using Unity to make Singleton-ness an implementation detail

  1. Bob Lee says:

    I use a similar example to open my Intro. to Guice talks, but I also highlight the benefits to unit testing: http://crazybob.org/2007/06/introduction-to-guice-video-redux.html

    In Guice, line 9 would like:

    bind(IImportantResource.class).to(MyImportantResource.class).asSingleton();

    However, I don’t agree that you should always completely separate any mention of the scope from the impl class. In Guice, I’d recommend using an annotation in this case:

    @Singleton public class MyImportantResource extends IImportantResource { …

    If you edit that class, the annotation tells you that the class has a single shared instance, and you need to consider thread safety.

  2. nymphets says:

    very useful article.

Comments are closed.