ASP.NET MVC: Resolve or Inject? That's the Issue…

Classes should have dependencies only on abstract, rather then concrete, classes. To get around this, you can choose between Service Locator and Dependency Injection techniques. ASP.NET MVC uses 'Dependency Resolvers' which are Service Locators. When designing ASP.NET MVC applications it is open to you to decide whether to resolve or inject, so what are the pros and cons? Dino explains.

I  teach a class about the principles and patterns of effective software design. I often disconcert the attendees by saying that, although I perceive a great deal of emphasis in the value of Dependency Injection, I don’t believe that Dependency Injection justifies all of the attention. Dependency Injection is just an implementation detail; what really matters is the principle behind it-the Dependency Inversion principle. If you’re familiar with the acronym SOLID, well, the Dependency Inversion principle is just the “D” in the acronym. By the way, SOLID results from the initials of five design principles that are reckoned to be essential in Object-Oriented software design. These five principles are:

  • Single Responsibility
  • Open/Closed
  • Liskov’s principle
  • Interface Segregation
  • Dependency Inversion

Nearly all of these principles are mere vectors in the sense that they show you the direction but don’t give you concrete guidance on how to do things. Let’s take the Single Responsibility principle as an example. All it says is that you should endeavor to write your classes so that you later have just one reason to change them. The idea behind the principle is that classes should be much more cohesive than they often are. The methods they are made of should be logically related and form a single chain of responsibility. As you can see, the principle heralds a clear and shared idea but it doesn’t give you a step by step procedure on how to accomplish it.

Inside the Dependency Inversion Principle

The Dependency Inversion principle, instead, has a fairly obscure formulation but can be translated into an extremely detailed set of implementation steps. The Dependency Inversion principle says that classes should not have dependencies on concrete classes but only to abstractions. Translated for humans, it means that you should be using interfaces to abstract all of the critical dependencies of a given class. If, for example, your class needs to use a Logger component, then the best you can do is to make your class aware of an ILogger interface rather than a Logger class. In this way, you can change the implementation of the logger class at any time (and for how many times you want) without breaking the host code.

The implementation of the Dependency Inversion principle is bound to an algorithm that passes a list of dependencies to the core code. Let’s have a look at the following code:

Clearly, the MyComponent class has a dependency on the Logger class. If we decide to change it to ILogger, how can we get a reference to an actual class that implements the interface?

To implement the Dependency Inversion principle, you have the choice of two main patterns: Service Locator and Dependency Injection. The former allows you “resolve” a dependency within a class; the latter allows you to “inject” a dependency from outside the class. The following listing exemplifies what it means to resolve a dependency:

You have a dependency resolver component that typically takes a type (commonly an interface) and returns an instance of a concrete type that implements that interface. The match between the type that is passed and the concretely-instantiated type is hidden in the implementation of the locator component. This pattern is known as the Service Locator pattern. Here’s another approach:

In this case, the MyComponent class receives the ILogger component to use from the outside world. Surrounding classes will take care of the initialization of the logger before passing it down to MyComponent. This is the essence of the Dependency Injection pattern.

What’s the difference (if any) between Dependency Injection and Service Locator? Both patterns are good at implementing the Dependency Inversion principle. The Service Locator pattern is easier to use in an existing codebase as it makes the overall design looser without forcing changes to the public interface. For this same reason, code that is based on the Service Locator pattern is less readable than equivalent code that is based on Dependency Injection.

The Dependency Injection pattern makes it clear since the signature  which dependencies a class (or a method) is going to have. For this reason, the resulting code is cleaner and more readable. What about ASP.NET MVC?

Dependency Inversion in ASP.NET MVC

ASP.NET MVC is designed with several extensibility points, but generally it lacks a comprehensive support for dependency injection. A service locator is probably the most effective way of making an existing framework more loosely coupled by the addition of new extensibility points, because it is the least intrusive solution. A service locator acts as a black box that you install in a specific point and let it figure out what contract is required and how to get it. ASP.NET MVC has a number of extensibility points, which are system components that can be replaced with custom components. Table 1 lists the known extensibility points as of ASP.NET MVC 3.

Provider Description
Action Invoker // In the constructor of a controller class controller.ActionInvoker = new YourActionInvoker();
Controller factory // In global.asax, Application_Start var factory = new YourControllerFactory(); ControllerBuilder.Current.SetControllerFactory(factory);
Dictionary values // In global.asax, Application_Start var providerFactory = new YourValueProviderFactory(); ValueProviderFactories.Factories.Add(providerFactory);
Model binder // In global.asax, Application_Start ModelBinders.Binders.Add(typeof(YourType), new YourTypeBinder());
Model binder provider // In global.asax, Application_Start var provider = new YourModelBinderProvider(); ModelBinderProviders.BinderProviders.Add(provider);
Model metadata // In global.asax, Application_Start ModelMetadataProviders.Current = new YourModelMetadataProvider();
Model validator // In global.asax, Application_Start var validator = new YourModelValidatorProvider(); ModelValidatorProviders.Providers.Add(validator);
TempData // In the constructor of a controller class controller.TempDataProvider = new YourTempDataProvider();
View engine // In global.asax, Application_Start ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new YourViewEngine());

Table 1. Extensibility points in ASP.NET MVC.

Until ASP.NET MVC 3, there was no standard way to register custom components. Each component listed in Table 1 requires its own API to be integrated in a user application. Starting with version 3, ASP.NET MVC introduces a new (optional) model based on dependency resolvers. To replace a system component, you can either take the route described in Table 1 or register a dependency resolver for the type. The ASP.NET runtime will then detect the dependency resolver and invoke it whenever appropriate.

A dependency resolver is just a service locator integrated with the ASP.NET MVC codebase. Resolvers are a way to add the implementation of the Dependency Inversion principle into an existing (large) codebase. For the size and complexity of the codebase, the use of Dependency Injection is less appropriate because it would have required changes at various levels in the public API. This just isn’t an option for a framework such as ASP.NET MVC. Let’s find out more details about the implementation of dependency resolvers in ASP.NET MVC.

Defining Your Dependency Resolver

An ASP.NET MVC dependency resolver is an object that implements the following interface:

The logic you put in the resolver is entirely up to you. It can be as simple as a switch statement that checks the type and returns a newly created instance of a fixed type. It can be made more sophisticated by reading information from a configuration file and using reflection to create instances. Finally, it can be based on Unity or any other IoC framework. Here’s a very simple, yet functional, resolver:

The code next shows a resolver that uses Unity (and its configuration section) to resolve dependencies.

You register your own resolver with the ASP.NET MVC framework through the SetResolver method of the DependencyResolver class, as shown below:

If you use an IoC framework from within the resolver then you need to figure out the best way to provide it with the list of registered types. If you prefer to pass this information via fluent code, then you need to fully configure the IoC container object before you create the resolver. If you intend to configure the IoC using the web.config file then, as far as Unity is concerned, you can use the default constructor of the resolver which includes a call to load configuration data. Note, however, that you may need to change this code if you target a different IoC framework.

Overall, the dependency resolver is an internal tool that developers can optionally use to roll their own customized components instead of system components. The power of dependency resolvers is limited by the use of them that ASP.NET MVC makes. Resolvers are invoked in well- known places to achieve well known goals. In other words, if ASP.NET MVC doesn’t invoke the resolver before creating, say, the controller cache, there’s not much you can do to replace the built-in cache with your own one.

Using Resolvers in Applications

It turns out that a dependency resolver is nothing more than the name that ASP.NET MVC uses for a service locator. How would you write one for a real application? The answer is that you have one resolver per application and write it to serve as many as customizations as you like. Here’s a slightly more specific version of the sample dependency resolver that we considered a moment ago.

The GetService method receives a type to resolve, and checks it against a list of known types. For some known interface types, it may simply return a manually-created instance of a known type. For other types it may return nothing, meaning that the resolver is not able to resolve that type.

An ASP.NET MVC dependency resolver has no way to resolve the same type in different ways during the lifetime of the application. While this may be a significant limitation in the implementation of a generic service locator, it is much less of a problem in the specific context of ASP.NET MVC. Dependency resolvers are an internal feature of ASP.NET MVC and only the internal code of ASP.NET MVC decides when and how to call application-registered resolvers. In the end, your resolvers will be called only in a limited number of circumstances, and the interface is more than acceptable.

So Should You Resolve or Should You Inject?

Should You Resolve or Should You Inject? If you look at this question in terms of the effectiveness of the design, then Dependency Injection is preferable to service location because it results in a cleaner design and a crystal-clear assignment of responsibilities. To use Dependency Injection, though, you may need to take the liberty of modifying the public interface of the API. This may or may not be acceptable depending on the context; it was not acceptable, for example, in the transition from ASP.NET MVC 2 to ASP.NET MVC 3. For this reason, Microsoft opted for the use of dependency resolvers, a fancy name for a classic service locator component. More realistically, a service locator is the only option you have to add an extensibility point to a large existing codebase that you don’t want (or are not allowed) to refactor significantly.


  • Rate
    [Total: 56    Average: 4.2/5]
  • jhonatantirado

    Finally understood dependency injection
    Excellent post! And good examples. I’ve been trying to understand this DI thing and finally got it thanks to your explanation.

  • jhonatantirado

    A post about DI
    Given I think I’ve finally understood this DI stuff, I wrote a post as an excercise and to check if I really got it.

  • Jonathan Allen

    Premature Generalization at its finest
    > If, for example, your class needs to use a Logger component, then the best you can do is to make your class aware of an ILogger interface rather than a Logger class. In this way, you can change the implementation of the logger class at any time (and for how many times you want) without breaking the host code.


    I change the implementation details of my logger all the time, yet I’ve never once found the need to expose an ILogger abstract interface.

  • Jonathan Allen

    > The Dependency Inversion principle says that classes should not have dependencies on concrete classes but only to abstractions.


    What is the specific problem you are trying to overcomes? Does that problem occur for ALL classes or only a very small subset?

    Back when we used COM we literally couldn’t reference a class by its name except to create it. Literally everything else we did was through one or more abstract interfaces that it implemented. Or in other words, the Dependency Inversion Principal was forced upon us.

    When .NET was created we made a conscious decision to abandon that principal. Numerous reasons were cited including issues such as how it impacts forwards compatibility and the proliferation of interfaces such as IFooEx2.

    Now this isn’t to say the it is completely useless. There are specific places where the dependency inversion design pattern are applicable. But to say that we should blindly apply that design pattern as if it were a universal principal is completely irresponsible.

  • nick harrison

    Re: What and Why?
    This may seem like over kill, but following a Test Driven Development methodology, you will always be guaranteed two implementations of the interfaces defined. The initial concrete implementation that you will run in production and mock test objects that you will use in unit testing.

    Starting with this principle and defining the interfaces from the beginning makes it easier to develop with testability in mind.

    As for the specific example that you refer to in your comments, the underlying implementation of something as nebulous as logger should never be tightly coupled to any logic. Code using a logging service should be oblivious to the implementation details of the specific logging service used. As soon as you have logic relying on using log4net or any implementation, you will have problems.

  • Neil

    Dependency Resolvers
    Great article, but just to add that if using Castle Windsor the IDependencyResolver lacks a release method which could cause memory leaks, (

    If you manually Resolve with Windsor you’re expected to Release.

  • Rippo

    Are both
    I use D.I. in my controllers CTOR and find it is very easy to unit test my controllers. If I use the Service Locator method above is unit testing just as easy? Thanks

  • Anonymous

    Logging and problems
    “As soon as you have logic relying on using log4net or any implementation, you will have problems.”

    What are these problems? The only time you would have a problem is if you decided to switch Logging tools – and I have yet to find a reason to switch once I’ve picked a logging tool – mostly because the logging tools available typically are pluggable anyway (so you can switch from text file to database logging, etc, with some configuration already). Or if you rolled your own logger – you could add that configurability in. The interface to any logging tool is generally pretty straight-forward as is.

    Logging is so often used as an example for DI, and I believe it is a bad example because it really isn’t that useful for that case. Now, avoiding writing a bunch of boilerplate logging code with AOP is a much better area where logging is a good example.

    There is certainly a place for DI and/or Service Location, but claiming that if you don’t use it for your logging code you will run into “problems” seems a bit naive to me.

  • nick harrison

    RE: Logging and problems
    I have had to switch logging once.

    I had everything hard coded to my own custom logger and thought that I would never need to change it. Calls to this logger were sprinkled through out my code.

    Then someone saw the logging application block from the enterprise library and thought that we had to adopt it. We were already adopting several pieces from the enterprise library.

    It took a solid week of hunting and changing and testing to find all of the points that needed to be changed.

    Then all was happy.

    Until we started using nhibernate which came with log4net. We opted to switch to log4net. Now this time it was a much simpler. In part because the enterprise library forced us to use an adapter layer because they do not guarantee forwards or backwards compatibility. So this time, all we had to change was the adapter layer much like we would have had to do in upgrading the version for EL.

    I have found that logging strategies is one area that is often changed. Applications probably have their RDBMS set in stone before the project is even a gleam in anyone’s eye, but how logging and instrumentation will be implemented is often subject to the winds of change.

  • Anonymous

    Dino great stuff here DI is all the rage here in the greater Portland area.
    I actually can’t remember a non injected application anymore.

    I will say injected applications can be a bit interesting to debug at times.

  • M. Lang

    provider model for data
    I just use provider model for abstracting away where i get my data. It is much easier than di frameworks to code, debug, and configure.

    I don’t see the need to inject MVC controllers. I am not going to swap out controller implementations. Action methods just need to get data from an abstraction and pass it to a view or return it as json.

    What i do need to swap out is whether i load from the Db, AppFabric, a webservice or something else. Provider model is perfect for that.

  • panos.roditakis

    how to resolve in mvc
    In mvc i would use actionfilters as service providers and not DI controllers because it does not feel right from the framework’s prespective.

  • turibbio

    Great Article!
    Very good article! Thanks Dino.