views:

169

answers:

3

I want to refactor some code using the Windsor IOC/DI framework, but my issue is that I have some Singleton classes and Factory pattern classes and I am not sure that one can implement a Singleton or Factory using DI.

Has anyone any ideas if that is possible and how?

+1  A: 

You don't, you let the IOC container do it. Where before you had explicit calls to a factory to get a singleton instance of an object, now you have the IOC container create a graph of objects for you, and it hooks everything up where it belongs. The container makes sure your singletons are singletons, and it acts as the factory.

If you are talking about having a factory decide at runtime what kind of object to serve up, DI isn't applicable there, except you can have the DI container inject the factory where you want it and manage its scope for you.

Nathan Hughes
Does the IOC framework also not have the ability to decide which object to serve up at runtime? So why use a factory in that way when using DI? I would use a factory more to create multiple instances of the same or similar classes...
Tony
I mean when using IOC, not 'using DI'
Tony
Typically IOC frameworks are pretty static, they create objects for you based on configuration (xml, annotations, property files, whatever), so no, there's not much ability to decide what to create on the fly.
Nathan Hughes
+3  A: 

The Singleton design pattern is at odds with DI. While it's possible to open up a Singleton so much that DI and the Open/Closed Principle starts to make sense, this will change the Singleton so much that it almost stops being a Singleton.

Thread safety is one big issue that comes to mind when you start opening up a Singleton.

It's much better to simply define your services and classes without considering their scope too much. If you have an object that you would like to share between multiple consumers, most DI Containers have the concept of a Singleton lifetime, which mimics the benefits of the Singleton design pattern without suffering from any of the drawbacks.

In short: Singletons are evil and should be avoided.

Abstract Factory, on the other hand, is very useful for DI purposes.

Mark Seemann
Singletons is something I use quite often, but reading this, it seems I'll have to change my strategy! I found them to be quite useful in certain situations... but I can see where you're coming from on Thread safety.
Tony
Thread safety is one thing, but the main problem is the violation of the Open/Closed Principle.
Mark Seemann
If I use a DI container to manage the scope of a singleton why is that a violation of OCP? Because I don't rely on static methods for the implementation I can still subclass it, I would think using a DI container for singletons lets me preserve OCP. ?
Nathan Hughes
If your DI container implements an interface and it just happens to be a Singleton then it doesn't violate OCP - it's just an implementation detail. The danger lies in in the fact that since it's a Singleton, it's available everywhere, so an inexperienced developer might use it directly and thus inadvertently create a tight coupling.
Mark Seemann
The common use of singletons (as opposed to using them for things like Flyweights, etc.), and DI both solve the same problem - location of a required dependency. Trying to combine them is pointless, as you end up solving the same problem twice. Just use DI - it'll give you more flexibility in the long run.
kyoryu
A: 

Most modern dependency injection frameworks allow you to specify whether they should serve up a single object instance for the life of the application (or request) or create new instances each time you ask for one.

You can also use a DI framework to resolve dependencies on factories when it's appropriate (if that's what you mean). You might do this if the factory selects a subclass based on runtime data, or if a dependent object needs to create many IFoo instances, in which case you might inject an IFooFactory.

Jeff Sternal
I do mean the latter of creating many instances of a certain class using a Factory, then having to inject the factory into some class.
Tony