Prefer Constructor Injection Over Property Injection

by Larry Spencer Wednesday, February 1, 2012 2:26 AM

Most Dependency Injection (DI) frameworks offer two ways to inject concrete classes into your objects: constructor injection and property injection (a.k.a. setter injection).

Barring very unusual circumstances, constructor injection is better.

Before stating the reasons why, let's review how constructor and property injection look with the Microsoft Unity DI framework. With constructor injection, the interface or abstract type is a parameter to the constructor; with property injection, the property is decorated with the [Dependency] attribute.

 

public class MyClass : IMyClass
{
    // When you resolve IMyClass to get MyClass, 
    // Unity will see the [Dependency] attribute and set
    // this property to an instance of the concrete type
    // that you have registered for IMyInterface in the 
    // Unity container.
    [Dependency]
    public IMyInterface PropertyInjected { get; set; }

    readonly private IMyInterface _constructorInjected;

    // When you resolve IMyClass to get MyClass, Unity
    // will also see that MyClass' constructor takes an
    // interface parameter. As with property injection,
    // it will fill the parameter with an instance of 
    // whatever type you have registered for
    // that interface.
    public MyClass(IMyInterface constructorInjected)
    {
        Contract.Requires(constructorInjected != null);

        _constructorInjected = constructorInjected;
    }
}

 

So why is constructor injection better?

First, it requires no special attributes like [Dependency]. This may sound trivial, but it's not. The presence of [Dependency] drags in the whole Unity library. That means that nobody can use your class without linking to Unity. (Other DI frameworks will have similar problems; they all use attributes for property injection.) It also means that your class will not work with a different DI framework.

Assuming that PropertyInjected is there for a purpose, the consumer of this class has two choices: he can have Unity set it for him, or he must set it on his own. Either way, what he must do won't be obvious. With constructor injection, intellisense and the compiler will both help you out. With property injection, you won't know that you forgot something until your program fails at runtime. On my team, we have found that discoverability is very important. If you write code that is consumed by others, you do everyone a favor if they can see at intellisense time what your code requires.

Finally, property injection violates the Single Responsibility Principle. The class that uses it has three responsibilities. First, it has taken upon itself the responsibility of choosing your DI software. Second, it must gather its dependencies from the DI container. And what was the third responsibility? (Oops.) Oh yeah -- it also does whatever you conceived as its primary task.

If you can think of a good reason for using property injection, please let me know in the comments. In the meantime, I think you'll be very happy with constructor injection.

Tags:

All | Dependency Injection

Comments (2) -

5/1/2012 12:50:35 PM #

One advantage of using property injection I find is that the code is explicitly marked as relying on a dependent object filled in from some DI framework. Constructor injection can be confusing to a new developer maintaining your code if they are unfamiliar with DI, naturally the person would be expecting your class to be instanciated somewhere with the required object(s) in the constructor, but they wouldn't find it easily increasing their time to understanding the code. Also, lets be reasonable, what are the chances you are going to change out the DI framework after having taken the trouble to learn it and integrate it into a project.

Will United States

12/26/2012 6:46:51 PM #

Many of the users of my Simple Injector IoC framework migrated from other frameworks (like Unity and Ninject) because they needed features or experienced performance problems with other frameworks. So the "what are the chances you are going to change the framework?" argument is not really strong IMO. Besides that, all agile methodologies focus on "preparing for change". Change is inevitable. Change will come. You'll better be prepared and you’d better be able two swap out your DI container when needed.

Besides not wanting to have a dependency on a framework, sometimes you simply can't. As Larry said, using the [Dependency] attribute drags in the whole DI framework. But when your code must be portable, your DI container might not be usable on all platforms. Unity for instance, is not available on Windows Phone. Besides, it would be really rude if you –as a base library developer- forced the mobile app team to use the container you happened to liked best.

I do agree with Will however that property injection is in fact easier to understand for developers who are not familiar with the DI patterns. It will however take you not more than a minute to explain that your team favors constructor injection over property injection. Every developer is (or should be) familiar with using a constructor. They might not understand why this is better, but that will come later. Hopefully your team practices code reviews to find violations of your coding guidelines and mentors new members on your team.

And although easy to understand, implementing property injection correctly is actually very hard. consumers may forget to set a property or change the dependency in the middle of the class's lifetime. This can lead to bizarre behavior. With constructor injection this can be easily prevented, since the dependency cannot be changed after the object is constructed.

One reason why many developers are often using property injection, is because they would otherwise have to inject too many dependencies into the constructor. Injecting many (say more than 5) dependencies into a constructor is very inconvenient and leads to lots of code bloat and noise (in C# at least). Blaming constructor injection itself however is unfair. If your class has that many dependencies, you are probably violating the Single Responsibility Principle anyway. It's not always a problem when you violate the SRP. Changes are though, that such class would become hard to maintain and hard to test.

Long story short, I completely agree with Larry here. For this reason I didn't include any injection attributes in the Simple Injector. I included a feature that allows users to do implicit property injection, but I regret it ever since. Implicit property injection (where the container will skip any property that can't be mapped) is even much worse than explicit property injection (where the container will throw an exception when the dependency can't be mapped - which is what Unity does with its [Dependency] attribute). This makes the DI configuration brittle and hard to verify. The verifiability of the configuration is one of the clear advantages of using constructor injection.

Steven Netherlands

Add comment