4

We can do DI in MVC either by implementing IDependencyResolver, or extending DefaultControllerFactory

I used to think that there was not much difference between these two different ways to do it.

However, I'm finishing my MVC book and it has me implement my own ControllerFactory (instead of extending the default), and in the CreateController method, it actually has:

(IController) DependencyResolver.Current.GetService(targetType);

So it looks like DefaultControllerFactory actually uses the DependencyResolver

There has to be a difference between the two, and I think it's just confusing me.

Questions

1) Is the book having me use the dependency resolver in order to simplify their implementation of a CustomControllerFactory, and the actual DefaultControllerFactory doesn't use it?

2) I'm having a hard time understanding the purposes of these two. I used to think it was just two different ways to implement DI, but the more I dig in the more I get a feeling they're completely different. It looks like the dependency resolver is where all the controllers get instantiated

3) Is there a best practice which trying to choose between the two? Perhaps some pro's and cons?

EDIT: For clarity, I've decided to upload the whole CreateController method:

  public IController CreateController(RequestContext requestContext, string controllerName)
  {
     Type targetType = null;

     switch (controllerName)
     {
        case "Product":
           targetType = typeof (ProductController);
           break;
        case "Customer":
           targetType = typeof (CustomerController);
           break;
        default:
           requestContext.RouteData.Values["controller"] = "Product";
           targetType = typeof (ProductController);
           break;
     }

     return targetType == null ? null : (IController) DependencyResolver.Current.GetService(targetType);
  }
Steve's a D
  • 3,801
  • 10
  • 39
  • 60

1 Answers1

6

Stick with DefaultControllerFactory.

IDependencyResolver is an example of the Service Locator anti-pattern, and should, IMO, never have been added to MVC (or Web API, for that matter). Although many people confuse Service Location and Dependency Injection, they are two extremely different attempts to solve some common problems related to programming to interfaces.

However, when you weigh the advantages and disadvantages of Service Locator versus DI, you'll find that Service Locator truly is an anti-pattern, because it introduces far more problems than it solves. Although it purports to solve some problems, it actually doesn't solve any problems that DI can't solve better.

Community
  • 1
  • 1
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • surely it only becomes an anti-pattern if you allow it to percolate through your architecture. As a collection to pre-populate services for the purpose of dependency injection its existence is fine. What sucks is when every layer of code is using this look up to find services. I've seen implementations that use IDR as somewhere to set the type and lifecycle of the objects but then those objects and all others use parameterised constructors and don't reference a service locator. – Quibblesome Dec 05 '16 at 09:35
  • What @Quibblesome writes seems to make sense, what is the advantage of extending DefaultControllerFactory over implementing IDependencyResolver, **if we use it correctly and don't use the DependencyResolver in other places in our code except for the Global.asax**? – BornToCode Aug 16 '18 at 14:20
  • @BornToCode If you do it like you write, you only need to extend `DefaultControllerFactory`. In that case, then, why go to the extra trouble of implementing `IDependencyResolver`? – Mark Seemann Aug 16 '18 at 15:58
  • @BornToCode See also http://blog.ploeh.dk/2014/05/19/conforming-container for some more details on why *Conforming Container* is an anti-pattern. – Mark Seemann Aug 16 '18 at 15:59
  • You gain automation of the tricky issue of creation order and you lose that clunky procedural code that does the initialization. However the cost is at debugging/troubleshooting time where the code is less clear because it doesn't exist. It don't think things are just "anti-patterns" they have trade-offs its just that the short-term benefits are not worth it most of the time. – Quibblesome Aug 17 '18 at 09:45
  • @Quibblesome That's a different distinction: that between [Pure DI](http://blog.ploeh.dk/2014/06/10/pure-di) and Container-based composition. That choice is unrelated to the choice betwen `DefaultControllerFactory` and `IDependencyResolver`. You can easily derive from `DefaultControllerFactory` and base the implementation on a DI Container of your choice. [My book](http://amzn.to/12p90MG) discusses how to do that. Here's [an example for Web API](http://blog.ploeh.dk/2012/10/03/DependencyInjectioninASP.NETWebAPIwithCastleWindsor) - it's quite similar. – Mark Seemann Aug 17 '18 at 11:02