Why IOC containers are considered as a way of reducing coupling? - c#

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.

Related

Can constructor initialization be used for dependency injection instead of having DI containers?

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.

What is a good strategy for initializing an IoC container within a class library?

I'm writing a class library (in C#) that will be distributed with applications I have no control over. My library is also a little bit security sensitive and thus I do not want to allow the calling app to do any configuration of the dependencies for the class library. It must be self-contained and initialize its own dependencies.
At the same time, I want it to be unit-testable and loosely coupled and I want to use an IoC container to manage the dependencies. At the moment I'm using internal constructors and [InternalsVisibleTo()] so that the unit tests can do manual injection. I prefer to use Ninject as my IoC container but that's sort of irrelevant to the question, I think.
I'm struggling to come up with a good strategy for initializing my IoC container in production, since the class library doesn't really have a defined entry point, it has a number of classes that can be instantiated with no way of knowing which one the app will use first.
I wondered if there may be some sort of AssemblyLoad event, and indeed the AppDomain seems to have such an event, but my assembly must already have been loaded into the AppDomain before I can even hook into that, so I would always miss the event raised by my own assembly being loaded. I also thought about using a static initializer or constructor, but I'm not really happy to pollute every possible class with IoC container setup because that makes them tightly coupled to the container. I don't want to decouple my code only to then couple it to the IoC container.
I have found a few other questions discussing this topic but none of them really deals with my situation. One suggested using a static initializer, another suggested that the application should always be the composition root.
Is there another way?
There is a contradiction between your requirements.
First, you don't want the Composition Root because of the security concern. Second, you want dependencies to be resolved by a container. But since the library doesn't control the container, pretty much anything can be injected into your code, including stuff that would try to break anything from inside.
One approach would be to have your dependencies explicit so that library clients are responsible for feeding your dependencies.
namespace Library
{
public class Foo1
{
// a classical IoC dependendency
public Foo1( IBar bar )
{
}
}
}
On the other hand, using a Composition Root which is an explicit external point of initializing your library still doesn't mean your library is polluted. CR works great with a Local Factory (aka the Dependency Resolver) which is responsible for internal object creation and it is set up from within the CR.
namespace Library
{
public interface IFoo { }
// local Foo factory, with a customizable provider
public class FooFactory
{
private static Func<IFoo> _provider;
public static void SetProvider( Func<IFoo> provider )
{
_provider = provider;
}
public IFoo CreateFoo()
{
return _provider();
}
}
// Bar needs Foo
public class Bar
{
public void Something()
{
// you can use the factory here safely
// but the actual provider is configured elsewhere
FooFactory factory = new FooFactory();
IFoo foo = factory.CreateFoo();
}
}
}
and then somewhere in the Composition Root (close to application's entry point)
// kernel is set up to map IFoo to an implementation of your choice
public void ComposeRoot( IKernel kernel )
{
FooFactory.SetProvider( () => kernel.Get<IFoo>() );
}
As you can see, instead of possibly providing multiple injection points in multiple classes, the Local Factory is a single injection point that provides a clean configuration of the whole library making it self-contained.
You could even have a provider that doesn't involve any IoC container but rather create a concrete implementation, thus making it easily testable without any container. Switching to another IoC is straightforward, you just provide another provider.
The larger your library is and your classes are cohesive (use each other often), the more convenient is to have a Local Factory. You don't need to rethrow dependencies between your classes (without a Local Factory, if your class A needs I and your B needs A then automatically B needs I), rather, all your classes depend on a single factory.
There are two scenarios here:
A) Your consumers aren't using your Ninject container:
If you don't want them to be able to provide alternate configurations (or are injecting internal classes), you must create a constructor that will resolve these dependencies yourself. This will be your point of entry.
B) You consumers are using your Ninject container:
You will need to expose your Ninject kernel instance to your consumers. This can either be wrapped in a ServiceLocator if you want to hide the fact that you are using Ninject, or by simply exposing the kernel itself. In either case, you can make it a property on a static class which will be your entry point.
From an internal standpoint, I prefer using option B, but as a frequent consumer of 3rd party libraries, I have never seen anyone expose their IoC container, not would I ever want them to. I just want to be able to instantiate a class, and not worry about any internal implementation or dependencies. You milage may vary, of course.

Pass parameter from a ViewModel to another with IoC

I'm trying to instantiate a SecondViewModel from a MainViewModel injecting in this second one paramaters that are services registered in the IoCContainer and objects from the MainVM.
The code is something of this kind:
class MainViewModel
{
public MainViewModel()
{
}
private string message = "the message";
public string Message { get; set; }
}
class SecondViewModel
{
public SecondViewModel(IService service, string message)
{
}
}
now, i know i can make the IoC Container inject a SecondViewModelFactory (that carries the service instance) into the MainViewModel, so it can create the SVM through it, but what if the implementation of IService is very heavy and i don't want to instantiate it but when i really need it.
And what if i have to instantiate other ViewModels in a similar way? Do I have to create tons of VMFactories and constructor's parameters?
And in case I use a generic ViewModelFactory, it would need to be instantiated passing all the services needed by every ViewModel I have, regardless if they will be created or not.
Do you know any better solution to my case?
In general, the creation of services should not be heavy. Their constructor should do nothing more than storing the incoming dependencies. If it uses some heavy resources in the background, they shouldn't be accessed through the constructor. This keeps the constructor simple (prevents you from having to test it) and allows the object graph to be composed very rapidly.
If there is really no way around this, there are basically two patterns you can apply:
1. Factories
You can inject a factory to delay the creation of a type. Factories are also useful when objects are created that should be controlled explicitly (for instance, instances that should be disposed as soon as possible). There are several ways of creating factories. Some people like to inject Func<T> or Lazy<T> dependencies into their services, but I find this too implicit. I rather inject an ISomeServiceFactory, since I find this more readable. Downside is that you need to define a new interface for this. However, if you find yourself having many factory interfaces, you probably have a problem in your design anyway.
2. Proxies
Instead of creating a factory, you can hide the service behind a proxy. This proxy can implement the same interface as the service and will do the delayed execution for you. This prevents you from letting the application take a dependency on a different interface (an IServiceFactory or Lazy<T> for instance). Especially Lazy<T> leaks details about the creation into the consumer of such a dependency. You can still inject a Lazy<T> into this proxy, if that's convenient. That's not a problem. That proxy would typically be part of your composition root and the rest of your application would still be dependend on your IService and not your Lazy<IService>.
Please be aware that the use of factories, proxies and lazy initiation does complicate the wiring of the container. So don't use if unless you measured that you really need it. They complicate things, because of the indirection, which makes it harder to follow interlectually. And they make it harder to verify your configuration using automated tests. For more information about verifying your container, take a look here and here.
Most IoC Containers supports Lazy dependency to with Lazy<> to avoid creating expensive class immediately.
So in your code, you can make lazy for your expensive IService:
class SecondViewModel
{
public SecondViewModel(Lazy<IService> service, string message)
{
}
}
You can use some popular IoC Containers and see how they support lazy loading: Autofac or NInject

Dependency Injection resolve and unit testing

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.

Best Practices for IOC Container

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

Categories