Why is MVC4 using the Service Locator Anti-Pattern?

10,181

Solution 1

That's an implementation detail that you shouldn't care about. The important thing is that now that the Web API uses the DependencyResolver to resolve dependencies for many different facilities, you will be able to use a real dependency injection whenever you want to plug into those facilities. So in your code you will be using a real dependency injection. If Microsoft didn't use the DependencyResolver then it would have been you that must have used it (as a service locator anti-pattern) in your code in order to resolve dependencies when you want to implement some custom functionality. This would have been bad for you. Now it's bad for Microsoft but you don't care about them.

Thus I'm left curious and confused why Microsoft would use a service locator in 2012.

Because designing a framework is not the same as designing an application using a framework. There are some different things to take into consideration when designing a reusable framework such as ASP.NET MVC rather than just what's written in the books. Some example is to design the framework in such a way that a person using this framework will be able to take advantage of the best practices written in the books in his code using this framework.

Solution 2

As Darin points out, ASP.NET MVC 4 is a Framework and is container agnostic. That's why it provides a service locator in the form of IDependencyResolver. This allows anyone to plug in their container of choice.

However, I wouldn't call this an anti pattern. This allows you to use the container of your choice, but it doesn't force you the application developer to use service location. If the framework forced the developer to use Service Location, then I would call it an anti-pattern. But the developer who builds an ASP.NET MVC application is free to use DI via constructor injection, property setup, or service location. It's their choice.

Look at all the ASP.NET MVC examples of dependency injection published by me or the ASP.NET MVC team. In pretty much all cases, they're using constructor injection. They're not using service location.

In fact, most of the ASP.NET MVC source code itself doesn't use service location to retrieve dependencies. There's a few key places where the MVC calls into the service locator for legacy APIs and such. But that's about it.

Share:
10,181

Related videos on Youtube

Tom Stickel
Author by

Tom Stickel

As a Full Stack developer, DevOps Engineer and a .NET developer I work with both greenfield and brownfield applications with a high affinity for continuous self-improvement and automation. .Net Core 1,2,4 / .net 5.0 Angular 2-12, React.JS, AngularJS, Typescript ASP.NET, C#, MVC 5 (4,3,2,1), Web Forms Web Api, Postman, Fiddler, SoapUI SQL Server / Oracle , Entity Framework Core,6,5,4, NHibernate, Linq SOA, WCF, jQuery, AJAX, JSON, XML Web API, Enterprise Architecture, VSTO, Continuous Integration, Bootstrap, IOC/DI Agile, Scrum, Team Foundation Server. Azure, AWS Node.js / NPM Python Cryptography - Security Git / TFS Gulp, Grunt, Bower, Nuget, NPM Ionic Mobile Yeoman Generators VMWare Esxi , DevOps

Updated on February 05, 2020

Comments

  • Tom Stickel
    Tom Stickel about 4 years

    After reading "Dependency Injection in .NET" by Mark Seemann I stay away from the Service Locator which is an anti-pattern.

    Upon reading the release notes on MVC 4 I see:

    Improved Inversion of Control (IoC) via DependencyResolver: Web API now uses the service locator pattern implemented by MVC’s dependency resolver to obtain instances for many different facilities.

    Thus I'm left curious and confused why Microsoft would use a service locator in 2012.

  • Sebastian Weber
    Sebastian Weber about 12 years
    +1 Frameworks follow different rules than applications. You want to keep a framework container agnostic (in case an application that wants to use the framework already uses a different container) and you usually don't want to enforce the usage of DI on those applications (as they might not want to use DI at all).
  • Mark Seemann
    Mark Seemann about 12 years
    I don't buy the argument that just because it's a framework, a Service Locator is appropriate. Yes, frameworks are different than applications, but it's perfectly possible to write a framework without using a Service Locator. Just look at ASP.NET MVC 1 and 2, or even something as complex as WCF. The problem with DependencyResolver in ASP.NET MVC 3+ is that it's not just an internal implementation detail, but rather being published and touted as public 'DI support'.
  • Sebastian Weber
    Sebastian Weber about 12 years
    @MarkSeemann I had this discussion with the chief architect of a large enterprise framework. If you can tell me how to make such a framework container agnostic and not enforce the DI pattern on all applications that are written using that framework I would be more than glad to hear them.
  • Mark Seemann
    Mark Seemann about 12 years
    Here are some pointers: stackoverflow.com/questions/2045904/…
  • Sebastian Weber
    Sebastian Weber about 12 years
    @MarkSeemann Considering the quality of the developers I met at that company: how would you 'force' them to use the builders/facades instead of newing up classes and messing things up by working around a framework and pattern they don't understand?
  • Mark Seemann
    Mark Seemann about 12 years
    There's no solution to the problem of bad developers. That doesn't invalidate my points in any way. Service Locator isn't a remedy for that problem either...
  • Tom Stickel
    Tom Stickel about 12 years
    I respect Darin, but Darin hasn't written a book that I worship like Mark Seemann. At this point I need to do more research and see more answers.
  • Darin Dimitrov
    Darin Dimitrov about 12 years
    I would also be happy to see more answers. @MarkSeemann, please feel free to post yours. That's why SO is a great site - it offers contrasting opinions. Please correct me if I am wrong but you said that there's no solution to the problem of bad developers. And since we are talking about the Service Locator pattern and the developers that used this pattern happen to be those that designed the ASP.NET MVC framework I am somehow arriving at the conclusion that you are implying that bad developers designed this framework (actually the architects, as they take this kind of design decisions).
  • Mark Seemann
    Mark Seemann about 12 years
    I don't really feel inclined to second-guess the MVC development team. I'm not saying that they are bad developers and architects, but I think that in this particular case, they made some bad decisions. In general, I like the MVC framework, so in overall, I think they made more good than bad decisions. When I referred to 'bad developers' above, I was thinking about a completely different level of 'bad' :)
  • Darin Dimitrov
    Darin Dimitrov about 12 years
    @MarkSeemann, then it would have been nice to post this as answer. It looks that the OP is looking for more answers.
  • Tom Stickel
    Tom Stickel about 12 years
    That seems reasonable, I'm still wondering why I received this response back from Marcin Dobosz (blogs.msdn.com/b/marcinon) in a email to me him saying about Mark's book / and service locator being an anti-pattern he said: "I have not read the book so I'm not familiar with the argument for why it's an anti pattern. Could you clarify why you think it's a bad design?"
  • Tom Stickel
    Tom Stickel about 12 years
    To Clarify, I emailed Marcin who I know works for Microsoft, and was surprised that he never heard that the service locator has been called an anti-pattern ( this is easy to find on the internet) I am not trying to throw him under the bus, but it is an example I think of what Mark S. is referring to.
  • David Hollowell - MSFT
    David Hollowell - MSFT over 11 years
    you said: "Look at all the ASP.NET MVC examples of dependency injection published by me or the ASP.NET MVC team." Can you provide links to some you suggest? I have some service references that many of my controllers use. They get an object, which is provided to a model object (constructor or method) to do some work to form a model (viewModel if you will) which is provided to a View. my main reason for wanting to do IoC is from my test project I want to be able to provide something else that implements the IService from the ServiceReference w/o actually calling the Service from my test project.
  • Chris Woodward
    Chris Woodward about 11 years
    I see why it's needed for the legacy support and for the simple cases where DI is overkill. I just wondered why they didn't use System.IServiceProvider instead of creating a new interface that then needs new wrappers to be written for each real DI container?