Setter vs Constructor injection

Recently I’ve had a discussion with a collegue about Setter vs Constructor injection. For those who don’t know what I’m talking about a quick example:

Setter injection:

public class SomeClass {
	
	private SomeDependency someDependency;
	
	public SomeClass() {
		//Empty constructor
	}

	public void setSomeDependency(SomeDependency someDependency) {
		this.someDependency = someDependency;
	}
}

Constructor injection:

public class SomeClass {
	
	private final SomeDependency someDependency;
	
	public SomeClass(final SomeDependency someDependency) {
		this.someDependency = someDependency;
	}
}

Ever since I’ve used constructor injection, I’ve never wanted to go back. For a good reason I might add. Constructor injection is just better, no discussion. Please allow me to explain.

Safe construction

First of all there is safety. In the case of setter injection it is perfectly possible to create the object without calling the setter(s). This would leave SomeClass in an uninitialized state. With constructor injection this could never happen, you just can’t create the object without at least deliberately ignoring (null-ing) the arguments.

Also, if you add a new dependency and forget to add the dependency in the XML… you’ll end up with weird behaviour and NPE’s while running your code. If you use constructor injection is would fail on startup because the correct constructor couldn’t be found. Failing early.

Finalization

In the case of constructor injection you can make the dependencies final, this is something you just can’t do with setter injection. This will further ensure the atomicity of SomeClass, it just can’t exist without its dependency. And there are many many more reasons using ‘final’ is a good idea (google it).

But… isn’t constructor injection less readable?

The only argument I’ve heard made against constructor injection is the fact that it becomes unreadable if you have too much incoming dependencies. But that argument is completely invalid!

The problem isn’t the constructor injection, it is a code smell. If your class has too much incoming dependencies you should reconsider this class. There is a good chance it is doing too much or having too much responsibilities.

So, it is actualy a good thing that constructor injection becomes aweful with too much dependencies, it is a code-smell! If the list of incoming dependencies grows too large you need to refactor, not blame constructor injection.

With setter injection it wouldn’t be almost invisible, a bad thing.

Conclusion…

In every single way constructor injection beats setter injection, so please only use constructor injection from now, k? bye!