Paul Hammant's Blog: .Net Dependency Injection better practice
.Net Service Locators
Coming to me via a Reddit "today I learned" link to a 'new' abstraction in the .Net world called the Common Service Locator libraryExcept its not new, version 1.0 was released September 30th, 2008; It was just new to me.
I did a tweet expressing my extreme dislike, and Robin Clowers joined in a little to debate me. After a few we retired gracefully to email to debate some more. My problem was the static accessor to the container being global meant that this piece was not a facilitator of Dependency Injection or the older and encompassing Inversion of Control (IoC), but the antithesis of them. I'm arrogant enough to think that I kind of know this topic being one of the folks that helped start it all.
My claim is that .Net should not have abstraction in the design of 'Common Service Locator library'. ServiceLocators should be banished when the facilitate static public access, and more careful thought should be put into how assemblies can declare their needs and be injected into by the thing that controls them.
Accepting the challenge
Anyway, with an example in Java for Robin to look at where the container was completely hidden from components, but was otherwise a rudimentary DI web-app, Robin went on to make an equivalent in C# that leveraged separate assemblies and methods marked internal so that the other assembly could not leverage the methods designated as hidden to the components. He's blogged about it here which is a better writeup of the achievement than this. Here's the solution in GitHub. It is a little more complete than mine, as it uses a real DI container - StructureMap (by a former ThoughtWorks colleague). I might prefer Windsor being that it has a past in Apache's IoC project 'Avalon' as I do. Robin's example is nice though and I think it should be publicized more, and perhaps held as best practice.Java Dependency Injection
In Java-land it is not exactly squeaky clean. Spring has a static accessor too (lesser known admittedly). Java-Servlets make it necessary when you consider which plugin types can take injected dependencies:Java servlet component type |
Can be injected? |
Normally a problem in DI web-apps? | PicoContainer's extended Jetty server |
Servlets | no |
no | yes |
Filters | no |
no | yes |
Listeners | no |
no | yes |
JSP Tags | no |
yup, is a problem | not yet :-( |
It is only tags/taglibs that are problematic, because 99% of DI webapps can be written using the out of the box Spring (etc) supplied servlets/filters/listeners. The components themselves are closer to POJOs and for the most part know nothing of the servlet world.
Robin has left an open question to the .Net community:
"Do developers abuse service locators when they could be using dependency injection?"
I suggest that the issue is that they should not be able to. But then with that claim, I'm back at the start of this debate again.