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.
Related
here's an example of what i am talking about
public interface IService<T>
where T : class
{
List<T> GetAll();
T GetById(object id);
.......... other methods here
}
public class Service<T> : IService<T>
where T : class
{
... implement interface here
}
public class ServiceClient
{
private readonly IService<User> _service;
public ServiceClient(IService<User> service)
{
_service = service;
}
public ServiceClient() : this(new Service<User>()){}
}
can someone tell me the difference between this and a Dependency Resolver? I normally Use SimpleInjector for Dependency Injection, I just want to know the benefits of the Container over doing the above..
Thanks
Update
okay lets say I have setup my Containers now and removed the 'this' constructor initialization, I Want to now Test ServiceClient
Let use MS unit test for snippet
[TestMethod]
public void Given_Something_Should_Success()
{
// Arrange
// how do i make an instance of this in a test without adding the 'new Service<User>()' part
ServiceClient client = new ServiceClient(new Service<User>());
}
and without changing my ServiceClient constructor to do this. Is it even possible to do that at this level? Sorry if this is a noob question i'm just trying to understand some things about it.
public ServiceClient(IService<User> service = null)
{
_service = service ?? new Service<User>();
}
See this line of code:
public ServiceClient() : this(new Service<User>()){}
Now the ServiceClient is aware of Service<User> class and the assembly where the ServiceClient is will not build without having a reference to the assembly where Service<User> class is located. Furthermore, if Service<User> has additional methods which are not in IServiceUser<User>, then the developer may do this within the class:
(this._service as Service<User>).SomeMethodNotBelongingToTheInterface();
Now one can argue that an irresponsible developer will do that sort of thing, but that is beyond the point here.
To be totally decoupled from the concrete implementations, you should never call new and leave this to the Composition Root. Both your classes and your assembly should only work with the interfaces and be totally unaware of the concrete implementations. This guarantees that you can plug any implementation at the composition root level, and everything will work.
This does not mean that even POCO classes without behavior should be behind interfaces but just classes that require plug and play sort of behavior.
If you follow this pattern, you can also create architectural diagrams within Visual Studio and instruct which layer can have references to which assemblies. During build, the build will fail (if configured to fail) if the developer creates a reference to an assembly they are not allowed to reference.
At the composition root level, it is up to you whether you want to plug the classes into each other using an IoC container or doing it manually. But why do it manually if there are good tools (IoC containers) which can do this for you. You can have one config file where all the test classes are and another where the real classes are. You can instruct your whole program to run with either configuration with just one line of code: This is what I mean by plug and play. The whole idea behind dependency injection, loose coupling etc. is that your classes should not have code which is written against a concrete implementation.
In Container you would register your class and interface.
Benefits are , you have one ioc class which will take care of providing you right type.
So you can program against interface.
and you do not need to new up in your code.
this gives you also flexibility when you have to manage scope or mock some class.
Here is some example how you register via IoC (Autofac)
builder.RegisterInstance(new ServiceClient())
.As<IService>();
What using a Container gives you is a centralised place in your application to specify how your dependencies should be resolved.
Imagine you have many classes that wants to inject the same implementation of IService. By using your approach above, you would have to write that same code for all of those classes. If you would have used a container, specifying it there would be enough.
Also, many DIs gives you more functionality for sharing instances, maintaining life cycles of your injections etc, provide dependencies to your dependencies etc.
This is called Bastard injection and you shouldn't do this because is totally against the purpose of dependency inversion: to create decoupled and maintainable code. If you use a default implementation it means that you have to reference the project that contains the implementation of your service. Or worst you probably create the implementation of your service in the same library where it lives the interface.
On the other hand you might have a good default implementation. For example you might define this interface:
public interface IClock
{
DateTime Now { get; }
}
The obvious implementation of this interface is
public class Clock : IClock
{
public DateTime Now => DateTime.Now;
}
I wouldn't use though a public constructor for this, I would inject it via a Property and leave the constructor for another implementation (maybe a mock from your tests). Also SimpleInjector I think would shout about having two constructors. It is a tool which made me to read more about these ideas.
When the IService's implementation is something that talks with a database, or HTTP service, or a remote one, or with 3rd party library or with file system, then these are good reasons for you create a separate project, reference the one you defined the interface, create the implementation, then in your place where you setup the simple injector, you can bind the interface with the implementation (which requires here to reference both projects). If on a later time you need a diferent implementation you can simply repeat the process and change the composition root.
I'm currently using Ninject to handle DI on a C#/.Net/MVC application. When I trace the creation of instances of my services, I find that services are called and constructed quite a lot during a the life cycle, so I'm having to instantiate services and cache them, and then check for cached services before instantiating another. The constructors are sometimes quite heavy).
To me this seems ridiculous, as the services do not need unique constructor arguments, so instantiating them once is enough for the entire application scope.
What I've done as a quick alternative (just for proof-of-concept for now to see if it even works) is...
Created a static class (called AppServices) with all my service interfaces as it's properties.
Given this class an Init() method that instantiates a direct implementation of each service interface from my service library. This mimics binding them to a kernel if I was using Ninject (or other DI handler).
E.g.
public static class AppServices(){
public IMyService MyService;
public IMyOtherService MyOtherService;
public Init(){
MyService = new MyLib.MyService();
MyOtherService = new MyLib.MyOtherService();
}
}
On App_Start I call the Init() method to create a list of globally accessible services that are only instantiated once.
From then on, every time I need an instance of a service, I get it from AppServices. This way I don't have to keep constructing new instances that I don't need.
E.g.
var IMyService _myService = AppServices.MyService;
This works fine and I haven't had ANY issues arise yet. My problem is that this seems way too simple. It is only a few lines of code, creating a static class in application scope. Being as it does exactly what I would need Ninject to do, but in (what seems to me for my purposes) a much cleaner and performance-saving way, why do I need Ninject? I mean, these complicated dependency injection handlers are created for a reason right? There must be something wrong with my "simple" interpretation of DI, I just can't see it.
Can any one tell me why creating a global static container for my service instances is a bad idea, and maybe explain exactly what make Ninject (or any other DI handler) so necessary. I understand the concepts of DI so please don't try and explain what makes it so great. I know. I want to know exactly what it does under the hood that is so different to my App_Start method.
Thanks
Your question needs to be divided into two questions:
Is it really wrong to use the singleton pattern instead to inject dependencies?
Why do I need an IoC container?
1)
There are many reasons why you should not use the singleton pattern. Here are some of the major ones:
Testability
Yes you can test with static instances. But you can't test Isolated (FIRST). I have seen projects that searched a long time why tests start failing for no obvious reason until they realized that it is due to tests that were run in a different order. When you had that problem once you will always want your tests to be as isolated as possible. Static values couples tests.
This gets even worse when you also do integration/spec testing additional to unittesting.
Reusability
You can't simply reuse your components in other projects. Other projects will have to use that concept as well even if they might decide to use an IoC container.
Or you can't create another instance of your component with different dependencies. The components dependencies will be hard wired to the instances in your AppServices. You will have to change the components implementation to use different dependencies.
2) Doing DI does not mean that you have to use any IoC container. You can implement your own IDependencyResolver that creates your controllers manually and injects the same instance of your services wherever they are required. IoC containers use some performance but they simplyfy the creation of your object trees. You will have to decide yourself what matters more performance or simpler creation of your controllers.
I'm using the Simple Injector Dependency Injection framework and it looks cool and nice. But after building a configuration and use it, now I want to know how to change from one configuration to another.
Scenario: Let's imagine I've set up a configuration in the Global Asax and I have the public and global Container instance there. Now I want to make some tests and I want them to use mock classes so I want to change the configuration.
I can, of course, build another configuration and assign it to the global Container created by default, so that every time I run a test the alternative configuration will be set. But on doing that and though I'm in development context the Container is changed for everyone, even for normal requests. I know I'm testing in this context and that shouldn't matter, but I have the feeling that this is not the way for doing this... and I wonder how to change from one configuration to another in the correct way.
When doing unit tests, you shouldn't use the container at all. Just create the class under test by calling its constructor and supplying it with the proper mock objects.
One pattern that helped me out here a lot in the past is the use of a simple test class-specific factory method. This method centralizes the creation of the class under test and minimizes the amount of changes that need to be made when the dependencies of the class under test change. This is how such factory method could look like:
private ClassUnderTest CreateValidClassUnderTest(params object[] dependencies)
{
return new ClassUnderTest(
dependencies.OfType<ILogger>().SingleOrDefault() ?? new FakeLogger(),
dependencies.OfType<IMailSender>().SingleOrDefault() ?? new FakeMailer(),
dependencies.OfType<IEventPublisher>().SingleOrDefault() ?? new FakePublisher());
}
For integration tests it's much more common to use the container, and swap a few dependencies of the container. Still, those integration tests will not use the container that you created in your application_start, but each integration test will in that case most likely have its own new container instance, since each test should run in isolation. And even if you did use a single container from application_start, your integration tests are ran from a separate project and won't interfere with your running application.
Although each integration test should get its own container instance (if any) you still want to reuse as much of the container configuration code as possible. This can be done by extracting this code to a method that either returns a new configured container instance when called, or configure a supplied container instance (and return nothing). This method should typically do an incomplete configuration and the caller (either your tests or global asax) should add the missing configurations.
Extracting this code: allows you to have multiple end application that partly share the same configuration; allows you to verify the container in an integration test; and allows you to add services that need to be mocked by your integration tests.
To make life easier, Simple Injector allows you to replace existing registrations with new one (for instance a mocked one). You can enable this as follows:
container.Options.AllowOverridingRegistrations = true;
But be careful with this! This option can hide the fact that you accidentally override a registration. In my experience it is in most cases much better to build up an incomplete container and add the missing registrations afterwards instead of overriding them. Or if you decide to override, enable the feature at the last possible moment to prevent any accidental misconfigurations.
I am thinking about using of DI and Unity in my project. And I have a question: how it will reduce coupling? From my point of view, it is increasing of coupling, because:
I need to create UnityContainer and register all types there. It means that I need to have the reference to all assemblies in assembly where this container is created.
IUnityContainer UnityContainer;
//....
IUnityContainer UnityContainer= new UnityContainer();
UnityContainer.RegisterType<IMyService, CustomerService>();
I need to create an instance of my service using Resolve but it means that I need to have the reference to assembly with container.
var service = SomeClassWithContainer.UnityContainer.Resolve<IMyService>();
Have I misunderstood something or in reality it is increasing of coupling?
I think you misunderstood how your dependencies should be resolved.
1.) A reference to Unity should only be needed in your bootstrapping code which is at a single central spot in your application.
2.) Once bootstrapping is done all dependencies (ideally) are resolved using constructor injection which is automatically done by Unity if the containing class is resolved via Unity - it is trickling down the object graph. The example you use is really just the "service locator" pattern and not DI.
This does reduce coupling since instead of directly creating a concrete class your class depends on, you "inject" dependencies (again ideally some abstraction like an interface) into your class which allows you to substitute those dependencies with other classes i.e. in the unit testing scenario.
Your question contains an example of the Service Locator anti-pattern:
public class UsesMyService
{
private readonly IMyService _service;
public UsesMyService()
{
_service = SomeClassWithContainer.UnityContainer.Resolve<IMyService>();
}
}
This is fundamentally different than the Dependency Injection pattern because of the direction the information flows: in the above example, you reach out and ask for the service, whereas in the example below, you are handed the service:
public class UsesMyService
{
private readonly IMyService _service;
public UsesMyService(IMyService service)
{
_service = service;
}
}
This pattern, known as constructor injection, decouples the UsesMyService class from details about the surrounding infrastructure. Now, anyone with an implementation of IMyService can create instances of UsesMyService without having to know to configure a central static location.
How would they even know what to configure? They would either need the source code or some documentation telling them that the class depends on IMyService. The constructor parameter cleanly expresses that requirement to consumers without any external reference.
If you follow this pattern throughout your libraries, you bubble the responsibility of assembling the objects all the way to the outermost layer, known as the Composition Root. This single location, usually the top-level application class, is the only place with references to all of the libraries you are using. That is where the container lives, and no other class in your entire solution needs to reference it.
I'm using the Unity IOC container and I'm just wondering what is the best best way to access the container for multiple classes.
Should every class have an IUnityContainer member and then pass the container in by constructor? Should there be a singleton class with an IOC container?
How about asp.net development?
Could somebody guide me in the right direction? Thanks.
IMHO it is not advisable to inject the entire container into a class or to have an application wide static IoC service locator.
You want to be able to see from the constructor of a class (lets call it Foo), what kind of services/objects it is using to get the work done. This improves clarity, testability and degubability.
Lets say Foo only needs the email service, but I pass in the whole container and somewhere in the code the email service gets resolved from the container. In this case it will be very hard to follow. Instead it is better to inject the email service directly to state Foo's dependencies clearer.
If Foo needs to create multiple instances of the email service, it is better to create and inject an EmailServiceFactory (via the IoC container), which will create the required instances on the fly.
In the latter case, Foo's dependencies are still indicated as specific as possible - only the ones, that the EmailServiceFactory can create. Had I injected the whole container, it would not be clear what services provided by it are Foo's exact dependencies.
Now, if I later want to provide different instances of the email service, I swap it out inside the EmailServiceFactory. I could swap out the whole factory as well, if all the services it creates need to be swapped (e.g. during testing).
So at the cost of creating one extra class (the factory), I get much cleaner code and won't have to worry about curious bugs that may occur when global statics are used. Additionally when supplying mocks for testing, I know exactly what mocks it needs and don't have to mock out an entire container's types.
This approach also has the advantage, that now, when a module is initialized (only applies to Prism / Modularity), it doesn't have to register all of the types of objects it supplies with the IoC container. Instead it can just register its ServiceFactory which then supplies those objects.
To be clear, the module's initialization class (implements IModule) should still receive the application wide IoC container in its constructor in order to supply services, that are consumed by other modules, but the container should not invade into the module's classes.
Finally, what we have here is another fine example of how an extra layer of indirection solves a problem.
Put the IOC container at the highest level / entry point in the process and use it to inject dependencies in everything underneath it.
you can register the container in itself and have it injected like every other dependency property, like so:
IUnityContainer container = new UnityContainer();
container.RegisterInstance<IUnityContainer>(container);
classes that need to access it will have the following property:
private IUnityContainer unityContainer;
[Dependency]
public IUnityContainer UnityContainer
{
get { return unityContainer; }
set { unityContainer = value; }
}
thus, the container is injected whenever an instance of such a class is resolved/built up.
This is more flexible as it works for multiple containers within the same application, which would not be possible with the singleton pattern.
If all of your objects need a reference to the container then you should look into reworking the code some. While still preferable to calling new everywhere it still scatters the responsibility of building your object graphs throughout your code. With that kind of usage it strikes me as being used more like a ServiceLocator instead of a IoC Container.
Another option would be using the CommonServiceLocator, although it may be a pointless indirection, you may use the ServiceLocator.Current as the instance known by all classes
I have a post on this subject at my blog where I´m using something along the lines of t3mujin answer. Feel free to use it (don´t bother that it´s sharepoint related...that doesn´t matter):
http://johanleino.spaces.live.com/blog/cns!6BE273C70C45B5D1!213.entry