Sunday, 25 March 2012

Dependency Injection for Singletons

[Level T2]

This is more of a hypothetical and perhaps philosophical question, but anyway I will shoot:
Now that most DI frameworks support singleton lifetime would you still manually implement the Singleton pattern?
I have seen a lot people answering NO to the question. They believe that the decision to use a singleton pattern can change and changing the lifetime of the object is just change in one line of code or configuration.

But I would answer YES.

Reality is, the reason to use Singleton pattern is usually:

  • Creating the object is expensive
  • Object uses (and commonly caches) data that are expensive to create
  • Object has to collect and keep some state/statistics
Which of above is likely to change over time? I would say practically none. When relying on DI frameworks to do the singleton pattern for you, your class loses its design coherency when it does not communicate its need to be implemented as singleton.


So I personally would implement the Singleton pattern and then register the instance (this is Windsor):

UniversalContainer.Container.Register(
    Component.For<IXsltTransformer>()
    .Instance(XsltTransformerWithCaching.Current)); // .Current is the singleton instance 

As it can be seen, the class XsltTransformerWithCaching is responsible for performing XSLT or XML documents. As we all know, XSLT processor in C# spits out the code for the transformation and builds an assembly at runtime (similar to Serialisation) and if done over and over again, it can cause "memory leaks". As we all know, once an assembly is loaded, it cannot be unloaded - and do not ask for it, it cannot be done.

So I would prefer to bake the singleton into the class.

4 comments:

  1. I think you can achieve same result if you define a custom DI scope, and register your instance within that scope, and then you don't need to make XmltTransformerWithCaching Singleton.
    Otherwise you claim that DI fw is initialized multiple times during application life time.

    ReplyDelete
    Replies
    1. That is the point of the article that you can. You can easily use DI to simulate singleton but your class loses its intention as someone can change singleton configuration to transient. Thats why i prefer explicit singleton implementation.

      Delete
    2. Your are right and I understand that, but on the other hand if you really need to make your singleton class transient then you don't need to change the class code. What if you need to use same object as transient in other application or change object's lifetime to session or request scope in another application. My point is DI give you flexibility, although your class lose its singleton intention and pass it to DI.
      I think whoever can change the lifetime of a class in configuration or code (conventional DI), usually can change the singleton class code to make it transient as well.
      However, if I really want to use your technique, then I'll make my singleton class just a wrapper for real class that I can use it as non-singleton as well.

      At the end, I would like to mention that your blog is great and keep blogging.

      Delete
    3. Well we can agree to disagree but my whole point about this short post is that you would very rarely if ever need to change a class which needs to be implemented as singleton.

      You might change the instanciation of a normal class to singleton to save memory and GC but that class is not a real- singleton. Here I talk about real singleton classes.

      Delete