views:

245

answers:

2

I am using Dependency Injection in my code (with Ninject) and thought I was doing quite well until I came across a performance problem that was caused by a misunderstanding of where DI containers fit into your code. There seems to be a lot of information on how to use DI frameworks but not too much on where not to use them or how best to use them (at least that I could find)

I thought I would write out what I thought were some best practices and see if other people agree with me and what other best practises people can came up with.

  • Use one kernel per application or AppDomain
  • Use the DI container for long-lived Singleton objects only, use factories (or other methods) for short-lived transient objects)
  • Prefer Constructor Injection over Property or Field injection
  • Request objects, don't build them
  • others?? pointers to good blog entires/articles??
+3  A: 

Here's a short list of the most important points (some of which also appear in the OP):

  • Code should be unaware of which DI Container (if any) is used
  • Compose the entire application in the root of the application (the Composition Root)
  • Favor Constructor Injection

I can't say I agree with your point about Singleton vs. Transient objects. The whole point of DI is that an external mechanism (such as a DI Container) determines the life-time of any given dependency, not someone else, so you need to have all dependencies managed by the DI Container.

Mark Seemann
Hi Mark, see the discussion here (http://groups.google.com/group/ninject/browse_thread/thread/41ec03527da9f0f8) about performance of Ninject in applications. Like you I thought that the DI container should be used everywhere but the overhead of DI containers is such that creating large numbers of transient objects can be obtrusive. Your advice is great for web applications perhaps but not so much in other domains.
Jeffrey Cameron
I skimmed that discussion, but I think I agree with Nate there. DI should be used to resolve and inject dependencies, but if one is creating hundreds of thousands of objects through a DI container, there's something wrong with the overall design. That was never the intention of DI. I could have added another bullet point to my list: "Favor decoupling Volatile Dependencies over Stable Dependencies", but it's more a general design recommendation than a particular DI thing.
Mark Seemann
I agree regarding transient objects - most applications that use DI create large numbers of transient objects. Some containers (Unity and soon Autofac 2) default to transient rather than Singleton.I don't think "prefer singletons" could be seen as a best practice - it seems more like a comment on the performance of a specific container in a specific scenario.
Nicholas Blumhardt
+2  A: 

Use the DI container for long-lived Singleton objects only, use factories (or other methods) for short-lived transient objects)

But do use DI to inject the factories into where there needed.

flukus