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
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
You can use System.Web.Mvc.DependencyResolver.SetResolver(resovlveDependencyMock);
It's easy with Moq:
DependencyResolver.SetResolver(Mock.Of<IServiceLocator>(s => s.GetInstance(It.IsAny<Type>()) == cacheMock.Object));
Related
I'm moving from StructureMap 2.x to 3.x. One major change is that using ObjectFactory results in the following warning:
'StructureMap.ObjectFactory' is obsolete: 'ObjectFactory
will be removed in a future 4.0 release of StructureMap. Favor the
usage of the Container class for future
work'
So in most cases, the resolution is fairly easy: pass through IContainer as a constructor. Unfortunately this is not feasible for ASMX web serivces or attributes, both of which require a default constructor. That means I'm probably stuck with the Service Locator Pattern, property injection, or writing my own ObjectFactory implementation.
What's the preferred way to deal with this unfortunate problem?
Edit: It's worth mentioning that my container does an Assembly scan.
Per Jeremy Miller, himself:
Assembly scanning isn’t cheap and you (almost?) always wanna cache the
results. So, yeah, in that case you’re going to have to write your
own ObjectFactory. Someday all that bad old MS tech will go away.
So in this case, this implementation is what should be done.
The cleanest way I have seen to deal with this is to use .NET routing to take control of the entry point, then make a custom PageHandlerFactory implementation that takes the DI container as a dependency.
The custom page handler factory will then property inject the page/service after it is instantiated but before any of its events are called.
This is almost exactly the same way that IControllerFactory works with DI in MVC. In MVC, the container is injected into a custom IControllerFactory implementation at application startup, which effectively makes it a part of the application's composition root. In the case of ASP.NET, the IRouteHandler would effectively be part of the composition root.
I was unable to find a link to the source where I originally saw that implementation. But this one is pretty close. The primary difference is that one tries to use constructor injection, but the downside is that it requires full trust to do. I believe if you stick with property injection, you can do it with partial trust.
I'm building a MVC application with Autofac and EntityFramework. I have a large set of data repositories / business objects that use my logging interface (NLog). I have just started working with Autofac and would like to know the preferred way for property injection:
Pass ILogging as constructor property, for this I have to set each local property from the constructor and creates larger constructor footprints.
Register each object individually with Autofac (they do not share a generic interface)
Use an Autofac.Module to locate these objects and set the property with reflection
Create a generic interface ILoggerDependency and register this with Autofac, this way all objects are easely registred.
My preferred method (out of lazyness...) is to have a generic interface that I can register with Autofac.
I am not that familiar with Autofac, so I'll try to give you my best recommendation based on what I know.
If there is one thing a lot of people gets wrong with dependency injection, it has to be using it for automation. The goal of DI is not to remove magic from your code. If anything, it is quite the opposite.
Keeping that in mind, I would not even consider using reflection as it hides large amounts of fragile plumbing.
Next, interfaces in OOP are meant to express what an object can do. Being injected is definitely not an action an object can take, but rather something that is imposed on an object. Even though, it is a quick and dirty way to solve your issue, I would refrain from using it as it will denature the structure of your code.
I have trouble understanding what you mean by pass ILogging as constructor property. Basically, you mean to resolve the interface yourself in the constructor? This looks a lot like property injection which defeats the purpose of DI by adding a strong dependency on your container within your class. Basically, instead of depending on Log4Net, you end up depending on Autofac. To fix this, you would need to add a service locator and then you still end up with a similar problem. How do you inject your service locator?
This is why I would register each object individually. It lets your container do its job. It doesn't affect your code structure and abstractions. It doesn't uses reflection (magic). It doesn't force you to depend on your container within each class. Besides, it also gives you a centralized place to look for when adding or removing repositories from your code.
In my ASP.Net MVC application I have implemented a Custom ActionFilter to Authorize users.
I use CastleWindsor to provide dependency injection into all of the controllers as follows:
protected virtual IWindsorContainer InitializeServiceLocator()
{
IWindsorContainer container = new WindsorContainer();
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));
container.RegisterControllers(typeof(HomeController).Assembly);
ComponentRegistrar.AddComponentsTo(container);
ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
return container;
}
Within my CustomAttribute, I need a dependency that is used by all of my controllers, however I am unable to user Constructor based injection in an attribute.
So what's the cleanest way out here? How can I provide the dependency?
OK - this seems to be a duplicate of Database injection into a validation attribute with ASP MVC and Castle Windsor which has been answered.
Also How do I use Windsor to inject dependencies into ActionFilterAttributes.
Having read through the above, and the referenced articles - the key one for me is http://weblogs.asp.net/psteele/archive/2009/11/04/using-windsor-to-inject-dependencies-into-asp-net-mvc-actionfilters.aspx for anyone else who is interested.
You can't. Attributes are metadata. Putting behaviour into them is wrong. Putting dependencies is even worse.
Use your attribute as marker to denote objects to which you want to apply the behavior and implement the behavior elsewhere.
In MVC elsewhere usually means a custom action invoker that uses data from the attribute to provide the behavior you need.
I have a service (AccountService) which has around eight methods. One of these methods sends an email. I have another service (EmailService) which is constructor injected into the AccountService.
I was wondering whether it's necessary to do this because it feels like every time I add functionality with a dependency to a method I have to change all my tests where I'm mocking up the dependencies for the constructor. This feels like DI is actually making it harder to change things, rather than easier.
So I was thinking about using the DependencyResolver in my controller action which calls the AccountService to get hold of the EmailService and pass it in. However, will this affect my tests?
How would I go about testing the controller action that used the dependency resolver? Given that the account service is constructor injected by ninject into the AccountController.
Cheers.
Don't use the DependencyResolver in your Controller! Just use it to create the controller using Ninject (See https://github.com/ninject/ninject.web.mvc/wiki). Everything else should be created by Ninject using constructor injection.
Actually, Unit Testing with proper DI and a design that follows the SOLID principles is quite easy.
In the test fixture setup you do nothing else than creating a (dynamic) mock for each dependency and an instance of the object under test using the created mocks as dependencies. That way you have to call the constructor exactly once for all your tests for each class.
If testing is hard it's not because of DI but rather by either not following the SOLID principles (most likely the single responsibility principle) or because of bad tests e.g. Unittests that use real instances of dependencies rather than mocks or doing too much in your test fixture setup.
Have you considered using the Property DI or is it necessary to inject it into the .ctor?
BTW:for your tests are you using somekind of Mocking Framework (e.g. Moq, RhinoMocks)?
Hope it will help you.
I'm trying to learn dependency injection and have come across a problem, when unit testing the application.
I'm writing a console application and the container is created and initialized in Main(), it's available as a get-property in Program.Container, so anywhere in my application I can call Program.Container.Resolve<..>().
I have a ServiceValidator class like this:
public class ServiceValidator
{
private readonly IConfiguration _configuration;
private readonly IService _service;
public ServiceValidator(IConfiguration configuration, IService service)
{
_configuration = configuration;
_service = service;
}
In another class I use
ServiceValidator serviceValidator = Program.Container.Resolve<ServiceValidator>();
serviceValidator.VerifyVersion();
It's the call to Program.Container.Resolve that causes me problems in the unit test, as it hasn't been setup.
Is that a bad practice, to call resolve on the container? I could create the ServiceValidator instance in Main() and pass the object around, but that seems stupid as it would cause lots of parameters for the objects that are just passed around to the next method.
So I guess it's acceptable to call Resolve within a class, but then the container must be configured for the unit test. How should I do that, should I move the container to another place than the Program class? What would you recommend?
If it matters, I'm using Unity and C#
Thanks :-)
Is that a bad practice, to call resolve on the container? I could create the ServiceValidator instance in Main() and pass the object around, but that seems stupid as it would cause lots of parameters for the objects that are just passed around to the next method.
When you use dependency injection all the way, then you won't need to pass lots of parameters to objects. The constructor of each object should have as parameters only those dependencies which it itself uses directly - it won't know about the transitive dependencies of its direct dependencies.
So if you have a class X which requires a ServiceValidator, then class X will have a constructor parameter of type ServiceValidator. Then if some class Y uses class X, then class Y will have a constructor parameter of type X. Notice that Y knows nothing about ServiceValidator, so you don't need to pass the ServiceValidator from one class to another - the only place where it is used is when constructing X, and that is often done by a DI framework or in only one place in a hand-written factory.
Some links for more information:
http://martinfowler.com/articles/injection.html
http://www.youtube.com/watch?v=RlfLCWKxHJ0 - your question about passing objects around is answered starting 19:20 "Myth about DI"
I usually allow calls to resolve dependencies from the container in places like main although I still try to keep them to a minimum. What I then do is configure the container in an initialization method of a test class. I have it initialized with fake implementations for any test class which needs to call the container.
Test classes which don't call anything requiring the container be initialized are then able to ignore it and not use the fakes. I usually use mocks in those instances.
I also use the Microsoft Service Locator so that the dependency that I am taking is on something from the .NET Framework instead of on a specific container. This allows me to down the road use anything I want even a home brewed container.
You could use a static class as an initializer for your container. Something like BootStrapper.cs would fine. You can then reference the class methods both in your code and tests.
Well what you're technically doing is a service location in your class.
I remember reading this article a while back:
http://martinfowler.com/articles/injection.html
For my classes I never try to use Resolve in them. I create the objects through the container when I need them. For Unit testing, I either use some mock library and stub classes.
The problem lies in the fact that you are trying to test the Main method. This method is virtually impossible to unit test.
I would argue that it is best not to unit test your Main method because:
The emphasis of modern unit testing is about design
You should minimize the dependency on configuration in unit tests. Configuration can be tested with smoke or integration tests.