2

I am building an ASP.NET MVC 5 application using the repository and service layer design patterns. I have used unity to inject my services into my controllers.

This works nicely and until now I have not had a need to consider instantiating any objects requiring injection of interfaces outside my controllers. However I have a need for this when configuring my application startup to setup some users in the database.

For this I wanted to user my UsersService that I've built. And it occurred to me as the application grows there will surely be other occasions when I'll want to do the same, such as calling a service from within another service.

I see that I can instantiate a Unity container and call resolve on it to get my new instance of a service:

IProductService productService = container.Resolve<IProductService>();

However this kinda smells to me, having the container leaked all over my application seems like an anti pattern. So is there a better way to do this?

1 Answer 1

5

Unity and other dependency injection containers automatically do this. When you inject a service into a controller, it will automatically resolve the entire dependency graph of that service. Not only can you resolve dependencies of the service and its dependencies, you should inject dependencies into the service that needs them instead of the controller.

Any class (including the controller) that has more than a handful of dependencies is a code smell that you are violating the Single Responsibility Principle, and you most likely should refactor to aggregate services.

And yes, injecting the container to any point outside of the composition root is an anti-pattern called a service locator.

As for injecting services outside of the controller, it is important to distinguish between injectables and runtime data. For example, some try to inject services into DTO objects, attributes, static classes/extension methods, and other places where it is anti-pattern for services to be injected. For these situations, it is important to properly assess the situation and refactor toward a DI-friendly solution - favoring constructor injection over other alternatives and considering a service locator as a last resort. For example, if you are trying to make an extension method with a dependent service, most likely you have some functionality that itself should be a non-static service, DTOs should never be created from a DI container, and you may have to make use of more than one extension point in MVC where you inject the container within the composition root of the application, which does not constitute a service locator.

Is it worth it? Usually. What is gained? You gain the ability to change the application much more quickly than if you have a tightly-coupled application in ways that the designer of the application may not have even anticipated. So the extra cost of ensuring the application is loosely-coupled is usually more than recouped in ongoing maintenance of the project. As a side benefit, you gain the ability to easily unit-test each component independent of the others.

Sign up to request clarification or add additional context in comments.

1 Comment

Ok thanks for confirming the existence of the service locator problem. I can see that if I get more than about 3 services being injected its time to refactor. As to entire dependancy graph you mention, I take this to mean unity figures out what dependancies need to be injected, and what dependancies of those dependancies need also be injected and so on. This being the case, then if I'm outside the controller, how do I avoid something like this: IService1 service1 = new Service1(new Service2(new Service3())) where service1 depends on service2 which depends on service3;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.