Paul Hammant's Blog: .Net Dependency Injection better practice
.Net Service LocatorsComing to me via a Reddit "today I learned" link to a 'new' abstraction in the .Net world called the Common Service Locator library
Except 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 challengeAnyway, 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 InjectionIn 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
|Can be injected?
||Normally a problem |
in DI web-apps?
|PicoContainer's extended Jetty server
||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.
Some back historyDuring PicoContainer's initial design, and born perhaps of a prior patronage of Apache's (now cancelled) Avalon project, it was always clear that parent/child containers were the best large-system reality. There are hints to that elsewhere: IIS, Apache-Tomcat (etc) are containers for components that don't facilitate general dependency injection, but could with some rework. Amongst others, the PicoContainer team has reworked Jetty (the other main servlet container for Java) to allow DI of major components, but that's custom to us, and not interoperable with Spring or Guice. See table above.
August 20th, 2010