# Wednesday, January 27, 2010

In a reaction to Uncle Bob's recent post on Dependency Injection Inversion, Colin Decker writes that he doesn't consider the use of the single Guice @Inject annotation particularly problematic. As I read it, the central argument is that

annotations are not code. By themselves, they do nothing.

I'll have to take that at face value, but if we translate this reasoning to .NET it certainly holds true. Attributes don't do anything by themselves.

I'm not aware of any DI Container for .NET that requires us to sprinkle attributes all over our code to work (I don't consider MEF a DI Container), but for the sake of argument, let's assume that such a container exists (let's call it Needle). Would it be so bad if we had to liberally apply the Needle [Inject] attribute in large parts of our code bases?

Colin suggests no. As usual, my position is that it depends, but in most cases I would consider it bad.

If Needle is implemented like most libraries, InjectAttribute is just one of many types that make up the entire API. Other types would include NeedleContainer and its associated classes.

Java annotations may work differently, but in .NET we need to reference a library to apply one of its attributes. To apply the [Inject] attribute, we would have to reference Needle, and herein lies the problem.

Once Needle is referenced, it becomes much easier for a junior developer to accidentally start directly using other parts of the Needle API. Particularly he or she may start using Needle as a Service Locator. When that happens, Needle is no longer a passive participant of the code, but a very active one, and it becomes much harder to separate the code from the Container.

To paraphrase Uncle Bob: I don't want to write a Needle application.

We can't even protect ourselves from accidental usage by writing a convention-based unit test that fails if Needle is referenced by our code, because it must be referenced for the [Inject] attribute to be applied.

The point is that the attribute drags in a reference to the entire container, which in my opinion is a bad thing.

So when would it be less problematic?

If Needle was implemented in such a way that InjectAttribute was defined in an assembly that only contains that one type, and the rest of Needle was implemented in a different assembly, the attribute wouldn't drag the rest of the container along.

Whether this whole analysis makes sense at all in Java, and whether Guice is implemented like that, I can't say, but in most cases I would consider even a single attribute to be unacceptable pollution of my code base.

Thursday, January 28, 2010 4:08:59 AM (Romance Standard Time, UTC+01:00)
In addition to its own annotations, Guice supports the atinject API. This minimal 6-class package contains only the stuff you need to import in your application code and nothing you don't. These are standard annotations supported by Guice and other Java dependency injection frameworks.
http://code.google.com/p/atinject/
http://atinject.googlecode.com/svn/tags/1/javadoc/javax/inject/package-summary.html
Thursday, February 04, 2010 4:09:23 PM (Romance Standard Time, UTC+01:00)
Ninject does it's injection magic using an [Inject] attribute. I agree with you that sprinkling your code base with those attributes is problematic. Not only because of the direct dependency, but this switching IoC frameworks becomes much harder. The Common Service Locator project defines an interface for IoC implementations. This allows you to swap implementations. However, when your code is polluted with those attribute declarations, switching isn't easy anymore.
Thursday, February 04, 2010 4:41:16 PM (Romance Standard Time, UTC+01:00)
I'm no expert in Ninject, but last time I checked, the [Inject] attribute was optional.
All comments require the approval of the site owner before being displayed.
Name
E-mail
(will show your gravatar icon)
Home page

Comment (Some html is allowed: a@href@title, b, em, i, strike, strong) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview