Throw Out Your Dependency Injection Container

Dependency Injection

Dependency injection containers (aka inversion of control containers) seem to be common in most modern applications.  There is no argument against the value dependency injection, but I do have a couple arguments against using a dependency injection container.  Like many other design patterns and practices, over time the development community seems to forget the original problem the pattern or practice was solving.

Constructor & Setter Injection

Passing your dependencies via the constructor is generally a better way of injecting dependencies instead of  setters. Constructor injection gives you a much clearer definition of what dependencies are needed in order to construct the object into a valid state.  My dependencies fields are usually readonly, to prevent them from being externally set after object creation.

Regardless if you use constructor or setter injection with your container of choice, there is often one injection method that is seemingly rarely used or mentioned.  Pass your dependency to the method that requires it.

How often have you seen a constructor take a pile of dependencies via it’s constructor, to which those dependencies were used in a limited amount of methods.  I often see this when looking at CQRS Command Handlers.

class InventoryHandler
{
	private readonly IRepository _repository;
	private readonly IBus _bus;
	private readonly IValidateInventory _validation;
	
	public InventoryHandler(IRepository repository, IBus bus, IValidateInventory validation)
	{
		_repository = repository;
		_bus = bus
		_validation = validation;
	}

	public void Handle(ReceiveInventory cmd)
	{
		if (!_validation.IsAvailable(cmd.ProductId)) {
			throw new InvalidOperationException("Cannot receive inventory");
		}

		// Receive Product into Inventory
		var inventory = _repository.GetById(cmd.ProductId);
		inventory.Receive(cmd.Quantity, cmd.UnitCost);
	}

	public Handle(RemoveInventory cmd)
	{
		// Remove product from inventory
		var inventory = _repository.GetById(cmd.ProductId);
		inventory.RemoveInventory(cmd.Quantity);

		// Pub/Sub to notify other bounded context of inventory removal
		_bus.Send(new InventoryRemovedMessage(cmd.InventoryId));
	}
}

In this simplified example, IRepository is used in both Handle() methods. However, IBus & IValidateInventory are both only used in one method each.

Instead of passing the dependencies via constructor, pass the required dependencies to the method that requires it.

class InventoryHandler
{
	private readonly IRepository _repository;
	
	public InventoryHandler(IRepository repository)
	{
		_repository = repository;
	}

	public void Handle(IValidateInventory validation, ReceiveInventory cmd)
	{
		if (!validation.IsAvailable(cmd.ProductId)) {
			throw new InvalidOperationException("Cannot receive inventory");
		}

		// Receive Product into Inventory
		var inventory = _repository.GetById(cmd.ProductId);
		inventory.Receive(cmd.Quantity, cmd.UnitCost);
	}

	public Handle(IBus bus, RemoveInventory cmd)
	{
		// Remove product from inventory
		var inventory = _repository.GetById(cmd.ProductId);
		inventory.RemoveInventory(cmd.Quantity);

		// Pub/Sub to notify other bounded context of inventory removal
		bus.Send(new InventoryRemovedMessage(cmd.InventoryId));
	}
}

 

Nested Dependencies

The primary reason why I prefer not to use a dependency injection container is because it potentially masks a code smell.  Nested dependencies or over abstraction can add complexity by adding unnecessary layers.

Have you seen something similar to this before?

public class MyService(IRepository repostiory) { ... }
public class Repository(IUnitOfWork unitOfWork) { ... }
public class UnitOfWork(IDbContext dbContext) { ... }
public class DbContext(IDbConnection dbConnection) { ... }
public class DbConnection(string connectionString) { ... }

Code SmellIf you are using a dependency injection container, you may not have noticed the excessive and unneeded abstraction layers in parts of you application.  If you had to manually wire up up these nested dependencies through all the layers, it would be really painful.

Masking the pain by using a dependency injection container is making your application more complex.

Take a look at your application and see if you can remove your dependency injection container.   If you can, then what benefits did it provide?  If you can’t, ask yourself if you really need all those layers.

Idiotic Interview Questions

Interviews questions always seem to be a topic that comes up frequently at a developer peer group I attend and while at work.  In a recent .NET Rocks! podcast, they touched on this topic and brought up the Fizz Buzz Test.  We have all been in interviews where we are given some ridiculous programming question, that is “intended” to show the interviewer your problem solving skills.  Or maybe (I think likely) they ask these questions because they are the stock questions, and everyone asks them.  It’s like asking someone for their strengths and weaknesses.  Do you really think people aren’t telling you what you want to hear.  These stock questions have stock answers.

Back to the ridiculous programming questions.   If someone asked me today in an interview some asinine array sorting question, or better yet a problem that you rarely encounter in the real world, I think my answer would be: Google.

Most of the problems that I encounter in the real world have been already dealt with.  I do not need to come up with my own solution.  I’m not arrogant enough to think that my solution is the best.  Using available resources (ie, Google) to to find the best solution to a problem seems like a better answer.  After all, wasn’t the point of the question to see your problem solving skills?  Why not ask questions related to Patterns, Practices, and Principles?  If the interviewee can discuss SOLID principles, doesn’t the Fizz Buzz Test seem idiotic to ask?

Domain Driven Design Quickly

I just realized that it has been almost 10 years since Eric Evans wrote Domain-Driven Design: Tackling Complexity in the Heart of Software.  Although it’s not new, it is still gaining awareness  and is still very relevant.  I’ve mentioned DDD in many of my posts so I figured I needed to provide some resources.

If you are new to Domain Driven Design and want a summary instead of jumping into Eric Evans book, then Domain Driven Design Quickly is for you.  Produced by InfoQ.com, this cliff notes book provide introductions to all the fundamentals of DDD.

DDD Quickly can be downloaded free from InfoQ.

Also, while browsing InfoQ, I found an older video of Eric Evans discussing what he has learned since he wrote the book.  It’s a tad old, but still provides great insight.