1

I'm building an ASP MVC 3 application in which I use Unity as IOC container and I register it on the DependencyResolver. In my controller I can then do this:

DependencyResolver.Current.GetService(GetType(IViewAllPersonsHandler))

Then when I write my unit tests I redefine my mappings in my test to use mocked objects.

A colleague of mine told me that doing this is considered as an Anti Pattern.

Can anyone tell me whether this is the case and why?

I know that normally I should inject my dependencies in the constructor, but as my controller grows the constructors parameters get lengthy.

Thx

Luc Bos
  • 1,722
  • 1
  • 13
  • 24
  • You shouldn't call DependencyResolver from your controller, stick with constructor injection. Your controller seems to be doing way too many things. Could you maybe move some of the dependencies to other layers, maybe even a filter or splitting the controller. – frennky Jul 27 '11 at 07:55
  • I'm using a CQS architecture so for every operation I have a separate handler or command (eg: UpdatePersonBankCommand, UpdatePersonAddressCommand,...). I'll try and see whether I can split the controller but I'm not sure I can. – Luc Bos Jul 27 '11 at 09:37

3 Answers3

3

Most folks consider the service locator pattern an anti-pattern. Probably since one can get around it with some leg-work.

If you are doing it to limit the constructor parameters you could try something different. I use property injection. Since I use castle windsor the container injects public properties by default. Last I looked Unity did not do this and you had to use some extension to get that to work.

Other than that you could split your controller or delegate to tasks within your actions.

But I would also stay away from service locator from within you controller.

HTH

Eben Roux
  • 12,983
  • 2
  • 27
  • 48
  • I've read this blogpost about it http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx; If I use property injection then in what way is this different as I still need to know which dependencies are used by a certain action on my controller. It minimizes the problem but does not make it go away, correct me if I'm wrong. – Luc Bos Jul 27 '11 at 07:19
  • The dependencies don't go away but the dependency on the *container* goes away. – Eben Roux Jul 27 '11 at 07:35
  • @Eben Unity doesn't do property injection by default, but it doesn't need any extension for that, it uses an attribute to decorate a property for injection. – frennky Jul 27 '11 at 08:00
  • @frennky --- ah! unity may not *need* an extension but if memory serves there is one available so that it is not necessary to use attributes. I am not too fond of them attributes :) – Eben Roux Jul 27 '11 at 08:10
  • Looked at it about 18 months ago but looks like something you do yourself :) --- http://stackoverflow.com/questions/515028/setter-property-injection-in-unity-without-attributes – Eben Roux Jul 27 '11 at 08:25
1

You can use System.Web.Mvc.DependencyResolver.SetResolver(resovlveDependencyMock);

Adamy
  • 2,789
  • 3
  • 27
  • 25
0

It's easy with Moq:

DependencyResolver.SetResolver(Mock.Of<IServiceLocator>(s => s.GetInstance(It.IsAny<Type>()) == cacheMock.Object));
Co-der
  • 363
  • 1
  • 14
  • 1
    Could you please provide some more details? What NuGets do I need? How would a full example look like? Because with this information only I can't make it work... Thanks – nulldevops May 10 '19 at 08:24