When NOT to Use Dependency Injection (introductory)
If you have a bean that has a dependency you want to consider seriously using DI to supply that. So if your DAO needs a data source name or your Service needs a DAO bean, use DI to provide it to it. Even if you have a transient business object that depends on a singleton like a DAO, use DI to inject that dependency (this is a pretty common requirement if you're allowing your business objects to handle persistence via a composed DAO).
If however you have a Service Singleton and it needs to create a new bean, you may or may not want to use your DI engine, but if you do, you'll have to make a specific call to the engine as a factory. Let me give a practical example.
Lets say you have a UserService and you want to request a new User (a transient business object) from it. You call UserService.new(). What does UserService do? Well, if your User business object has no dependencies at all and you don't need to add advice to the business object methods (AOP) you could just createobject() right there in UserService.new().
If the User (a transient business object) DOES have dependencies, you're going to want to call your DI engine explicitly to get the bean with its dependencies. So you're going to want to do something like User = beanFactory.getBean("User"); and it'll return your User bean loaded with any dependencies (maybe UserDAO).
That is the basic case. If you want a DIFFERENT User object to be returned based on business rules, we're going to need an abstract factory which you can either call directly or configured into your DI engine as a factory so it can create the necessary bean and your DI engine can still inject dependencies into whatever it returned, but don't worry about abstract factories just yet - you'll know when you need one!
Make any sense?



Should you dive right into DI as you suggest (for any non-trivial OO application), or should you add DI to each class as needed (following YAGNI to the extreme)? If one object (A) only ever uses one type of each object it is dependent upon (B,C, and D), what is the use in having the extra layer of complexity for dependency injection?
It seems (at least without further explanation) that a programmer might want to wait until they needed another type with the same interface (E implements the same interface as B,..., G the same as D) (perhaps they are mock object, or perhaps they have some business function other than for testing).
If you find the need for DI in one object, then do you immediately use it for all other objects (since you're likely going to be using the DI framework anyway), or do you wait to add others as they occur?
Thoughts?
This is a no brainer to me - I'd rather code using punch cards than write a non trivial app without LightWire (even ColdSpring doesn't come close to what I need as I live for the programmatic config file). With DI I can keep a central "registry" of object dependencies, I don't have to worry about creating objects in the right order when I have complex dependency chains as it is done for me automagically, and beans are just where I need them to be when I need thm to be. In my in-house framework I call a single class file which is the framework and EVERYTHING from there on in (accessing controller, controller accessing service layer, service layer accessing DAOs, creation of transients with composed DAOs, etc) is handled by LightWire. And with a programmatic config file I can pass in a list of business objects and use loops to create all of the beans and dependencies so if I need a Metadata bean, an IBO, a DAO, a Service class and a Controller for each of 40 distinct business objects with some fairly consistent dependencies (IBO and Service need DAO, all need Metadata bean, etc.) I just pass in a comma delimited list of business objects inside my application config bean and it wires up the hundreds of beans in 30-40 lines of easily readable code.
In addition my system adds some automagic. When you use base methods you can end up with a lot of beans that don't actually contain any code (UserService.cfc won't contain anything unless I need to add a method to it that can't be described by parameterizing base methods and describing it as metadata). So, if there is no code in a bean, why have the file? Why not just instantiate the base class as IF it was the UserService instead (Liskoff in reverse). So my programmatic config includes a generic script that says "go look for the cfc in the project. If there, instantiate. If not, look for it in the shared library. If there instantiate. If not go instantiate the BaseService" and it does that for all business object Services, Controllers, IBOs and DAOs. I also have scripts that automagically just instantiate all of the custom data types for a project by reading the shared and project directories for data type classes, automatically instantiating them all and putting them into a facade, so when I want to add a new data type, I just need to create the file and don't need to add it to the config file - same with features.
Sure I could do all of this other ways, but it is so fast and easy doing it this way I couldn't imagine going back to what most other people do - I just don't have the time :->
I have just got into Coldspring and see the benefits it brings.
I now have a few beans with depenencies and used Coldspring without any problems. It was a application that hasn't many users so far so no performance problems with it so far.
I read Sean Corfield mention that using Coldspring for non-singletons is overkill so looked at a simple factory by Rob Gonda which does the job nicely (and which Coldspring manages). I have now discovered Lightwire so will look into this too.
As I am not at the AOP stage yet do I need Coldspring? I'm thinking a simple factory or Lightwire may do the job well on its own.
Or is there something that Coldspring does I'm missing that I'll kick myself down the line if I switch DI framework?
There are many benefits that ColdSpring provides. It has a bigger user community and more documentation and includes remote bean proxy generation as well as AOP. LightWire is simpler, but I find it is a great fit to my needs and I will be adding AOP and my own version of remote bean proxies to LightWire later this year.
You would probably be better asking on the ColdSpring mailing list for the things you might be losing if you went with a DI engine other than ColdSpring as there are plenty of developers there using ColdSpring every day who might raise issues I'd miss.