19

I am designing some architectural changes into a legacy ASP.NET application. I prototyped some classes for dependency resolution that mimic the ASP.NET MVC's IDependencyResolver. I won't post because it is pretty much the same interface, but in other natural language.

I figured out it might be considered Service Location, which in turn is usually (not fully in some cases) condemned in favor of Dependency Injection. Nevertheless, I couldn't find any recommendation against the use of the ASP.NET MVC's dependency resolution implementation.

Is the ASP.NET MVC's IDependencyResolver considered an anti-pattern? Is it a bad thing?

Douglas
  • 36,802
  • 9
  • 76
  • 89
michelpm
  • 1,795
  • 2
  • 18
  • 31
  • 3
    The IDependencyResolver is just a tool; how it's used is the pattern. It's an oversimplification to equate it with the Service Locator Pattern. Don't reference it from your code, and stick to constructor injection. – StarTrekRedneck May 16 '12 at 21:20

2 Answers2

27

If you look at the signature you will see that it's just a Service Locator with another name. Service Locator is an anti-pattern and I consider the relationship transitive, so I consider IDependencyResolver an anti-pattern.

Apart from that, the interface is also broken because it has no Release method.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • My fears become true. Thank you anyway, you do explain that very well in the 2010/02 post. For a complimentary reading on what to use instead I would suggest http://stackoverflow.com/questions/2176833/ioc-resolve-vs-constructor-injection – michelpm Apr 13 '11 at 19:49
  • 13
    While I agree with Mark about the Service Locator anti-pattern thing. However, no matter what you try, there must at least be some place in your application where you use the Service Locator (anti) pattern, because we need to resolve instances somehow. In MVC they effectively solved this by letting the framework itself resolve the root objects (controllers). For this to work, we need to supply MVC with a container and `IDependencyResolver` was defined as abstraction for this. So is `IDependencyResolver` a bad thing because it is service locator? I don't think so. – Steven Apr 13 '11 at 20:07
  • 8
    But, ASP.NET MVC has had IControllerFactory for exactly that purpose since 1.0, and it has served its purpose admirably. It's an Abstract Factory, so is mostly harmless. – Mark Seemann Apr 13 '11 at 20:09
  • http://stackoverflow.com/questions/1599811/is-it-bad-to-use-servicelocation-instead-of-constructor-injection-to-avoid-writin – michelpm Apr 13 '11 at 20:25
  • Perhaps the MVC framework is using the Service Locator anti-pattern because of its dependency on the IDependencyResolver interface. However, hooking into it is not necessarily bad. One can implement DI in an acceptable "non-anti-pattern" way using constructor injection with IDependencyResolver. – Jason Capriotti Feb 14 '12 at 21:51
  • 4
    Maybe we're disagreeing about how to use IDependencyResolver. I would never encourage folks to have IDR.Resolve() in their code other than the one place at the top of the App. Is that what's being assumed when using IDR, that I've got all my classes asking it for stuff? Nay! I'm a big advocate for constructor injection. I have to agree with Steven in that one has to resolve even the IControllerFactory somewhere. The framework originally did that manually, now it abstracts that with the IDR which it also uses for other stuff that used to be hard-coded in the framework. – StarTrekRedneck May 16 '12 at 21:12
  • 9
    When answering this question, perhaps a distinction should be made between implementing a Service Locator in a Composition Root and referencing your Service Locator all over the place throughout your code. –  Jul 12 '12 at 22:34
  • -1 I vehemently disagree with your premise that service locator itself is an anti-pattern. The service locator is an invaluable pattern when it is needed, and it fulfills roles that there are no other solutions to, other than poor implementations of the service locator pattern. – Chris Marisic Mar 10 '14 at 16:00
  • 1
    @ChrisMarisic My claim is falsifiable, so please prove me wrong (but please not in this thread): what role does it fulfill that there are no other solutions to? However, before you attempt to answer, you may want to scan [my blog](http://blog.ploeh.dk), because people have tried to prove me wrong since 2010, and none have suceeded. – Mark Seemann Mar 10 '14 at 16:07
  • @MarkSeemann I copied my reply from your blog. I wrote my comment about 2 years ago. I look back and I stand by my assertions are as accurate today as they were then. Without the service location pattern you cannot achieve inversion of control in a framework without coupling your framework to a specific container (including building one yourself). The only method is to depend on the service locator pattern and defer to the bits that will actually do the work. No other pattern exists there, all others would be poor implementations of service location. – Chris Marisic Mar 10 '14 at 16:36
  • The other case that service location is absolutely gorgeous is in.... wait for it... service orientated architecture. Prior to this past year I have never prevalently used service location in my apps, which has changed. Now my applications commonly have some core aspect that ultimately boils down to `DoWork(some object)` and able to build ultra-decoupled systems. A system that can effectively use service location has exceedingly low `temporal coupling`. Strong temporal coupling in a system is a far bigger threat than nearly any other facet to a maintainable and extensible system. – Chris Marisic Mar 10 '14 at 16:36
  • 1
    -1 While I appreciate what you are getting at, ServiceLocator has it's uses. Dependency Properties in WPF being one (they are static). Cross Cutting Static Services are another. The main reason for the downvote is that absolutions are never good when talking about architecture... Just to add, Caliburn.Micro makes use of a service locator in many places and does so quite elegantly... – McDonnellDean Mar 10 '14 at 16:46
  • 3
    But... those are examples of horrible designs, based on shared state! Putting lipstick on a pig doesn't prove that Service Locator is a good pattern. There's always a better way to solve problems like that. – Mark Seemann Mar 10 '14 at 17:47
  • @MarkSeemann so your statement is ASP.NET MVC is an example of horrible design? I'm going to disagree there. Using service location for... service location is a horrible design? Once again we're at a stark disagreement. – Chris Marisic Mar 11 '14 at 18:24
  • 2
    Yes, that part of ASP.NET MVC (and certain other parts, too) is, indeed, horrible design. – Mark Seemann Mar 11 '14 at 18:27
  • @MarkSeemann sorry Mark you're just flatly wrong there. I can't talk about the internals of it, but it is extreme elegance to the users of the MVC framework. A framework is entirely about providing elegance to the users of the framework, it is the #1 concern. User Experience is always the #1 concern, the UX of a framework is a developers interaction with it. – Chris Marisic Mar 12 '14 at 14:30
  • 1
    @ChrisMarisic You may want to look at the discussion between Jeff Soper and me in [the comments section of this blog post](http://blog.ploeh.dk/2012/10/03/DependencyInjectioninASP.NETWebAPIwithCastleWindsor). It clearly describes why certain compositions are impossible with Service Locator. A technical solution that makes certain desirable features impossible, when there's clearly a better alternative, hardly qualifies as 'elegant'. – Mark Seemann Mar 15 '14 at 18:33
  • @MarkSeemann you conclude that blog post with `GlobalConfiguration.Configuration.Services.Replace`, you just implemented your own Windsor service locator... `WindsorCompositionRoot` is a service locator. – Chris Marisic Mar 17 '14 at 18:57
  • 2
    @MarkSeemann I'm sorry you can't have it both ways, you're making arguments based on pedantics. You really should re-evaluate your views. The Service Locator is simply a valuable pattern that serves a role that no other pattern completes. Just like all patterns it can be misapplied. You can't definitively state "it is an anti-pattern" and then immediately say the same functionality over here "but this isn't a service locator, so it's fine". If it walks like a duck, and quacks like a duck, it's a duck... or something emulating a duck. – Chris Marisic Mar 19 '14 at 21:04
8

I don't believe so... You can inject any IoC you want into ASP.NET MVC, which seems like a pretty good pattern to me.

Here's a blog post about injecting Unity into ASP.NET MVC 3.

  • It looks like IDepedencyResolver implements service location. The question is: does it? Why is this implementation any better than others service locators? – michelpm Apr 13 '11 at 18:46
  • 1
    @michelpm: [It doesn't implement anything.](http://msdn.microsoft.com/en-us/library/system.web.mvc.idependencyresolver(v=vs.98).aspx) –  Apr 13 '11 at 19:06
  • @michelpm the purpose is to a create a common interface so you can use an IOC container handle the object graph construction of MVC Controllers in a fashion that is entirely agnostic to the container. The interface creates the contract so the MVC implementation can defer to "magic give me things" method. Without this pattern you would need to build your own base framework do dependency inversion. – Chris Marisic Mar 10 '14 at 16:02