MVC Controller Resolver Cache

I recently faced a curious problem: I was using a third party IoC container in an MVC 5 (ASP.NET 4.*) app. In it, I had registered a service with a lifetime of transient, meaning, each resolution would return a different instance.

As you may know, in an MVC controller, there are two ways by which we can resolve a service using the MVC infrastructure:

I was using Controller.Resolver to resolve a service, but, after the first resolution, I would alwas get the same instance! It turns out that, by default, Controller.Resolver does not resolve to the same as DependencyResolver.Current, but instead uses an internal implementation that caches resolved services(DependencyResolver.CurrentCache, an internal property)! This means that it is virtually unusable with any lifetime other than singleton!

There are at least three workarounds:

If you were to ask me, I’d go for option #3.

                             

9 Comments

  • The third one is the only one to use in order to make the application unaware of dependency injection framework and really make reusable software.

  • He. Nice one!
    What 3rd party IoC container were you using?

  • Your tic tacks are very good, it would be more help full to juniors if you explain it with code. it will be highly appreciated.

    thanks
    and best regards,

  • Option 3, constructor injection, is not a workaround. It is the correct approach. If you have a container and are "doing dependency inversion", then (with one exception) using service locator is an acknowledged anti-pattern.

  • Also, "transient" is unlikely to be the correct lifestyle for controllers and their dependencies. Most IoC containers have the concept of a "per web request" lifestyle, so you should use that. Components resolved using transient lifestyles must be released manually, otherwise you basically have a memory leak. If you use one of the more appropriate lifestyles for your scenario, then the lifestyle manager in your IoC of choice should release components at the right time.

    HTH.

  • Very good info, but what were you using the Container for at controller level ? :)

  • Hi, guys!
    I apologize for the delay in approving your comments, but my blog engine stopped notifying me of new comments! :-(
    As to them:
    - @mark: it doesn't really matter; I am a fan of Unity, but I ordinarily use AutoFac at work;
    - @neil: you are right, I use the term "workaround" as a way to solve the problem; I agree it is the best one - they say constructor injection is the purest form of DI; also, I simplified things a bit - I am not using transient, I am well aware of per request lifetime, but thanks!
    @all: thank you for your comments, please, keep dropping by and giving feedback!

  • @Fernando: sometimes I need to use a Service Locator! :-)

  • Only now, working on a legacy app bumped into this. Thanks. Explains my current issue very well.

Add a Comment

As it will appear on the website

Not displayed

Your website