So, you have heard of Dependency injection (DI) but are having a hard time grasping the concept? Well you're not alone, DI can seem quite complex at first! Fortunately dependency injection is easy to learn and understand, and once you start practising it chances are that you never want to go back to do things in the "old bad" ways.The old bad ways
Let's say that you have a class called Car and Car need to call a method in the Engine class. Today you might either have to provide the instance to Engine manually when you create a Car:Or perhaps create Engine in the Car's constructor:
var generator = new Generator(); var engine = new Engine(generator); var car = new Car(engine);
Is this bad? Not always, but it can be much better!
public void Car() { _engine = new Engine(); }
The Dependency Injection way
Let's say that you'd like to implement the following using Dependency Injection. This is how you can do it:
1) Extract your classes method definitions to Interfaces:2) Create your classes so that all their dependencies are fed to them as Interfaces through the constructor and store them in private variables:
public interface IEngine { void Start(); } public class Engine : IEngine { public void Start(); }
3) In the entry point of your application, register what instance of what class that should be provided for each interface with an IoC container (I'm using Autofac in this example):
private readonly IEngine _engine; public void Car(IEngine engine) { _engine = engine; }
This means that whenever a constructor asks for an instance of type IGenerator the IoC will provide it with an instance of Generator and so on.
var builder = new ContainerBuilder(); builder.RegisterType<Generator>().As<IGenerator>(); builder.RegisterType<Engine>().As<IEngine>(); builder.RegisterType<Car>().As<ICar>(); var container = builder.Build();
4) Start the top-level instance (and all underlying instances will be created automatically for you):The following will happen:
var car = resolver.Resolve<ICar>(); car.Start();
* The IoC will try to create an instance of ICar using the class Car
* Doing this it will notice that Car needs an instance of IEngine in order to be constructable
* The IoC will then try to create an instance of IEngine using the class Engine
* Doing this it will notice that Engine needs an instance of IGenerator in order to be constructable
* The IoC will then try to create an instance of IGenerator using the class Generator
* The IoC can now create an instance of Engine as all it's dependencies have been met
* The IoC can now create an instance of Car as all it's dependencies have been met
* The instance is returned to you
* You can invoke the method StartWhy is this good?
This has several benefits. The most important is that it automatically makes your code testable. As you are using interfaces everywhere, you can easily provide another implementation in your unit tests. This means that your tests will be much easier to set up as well as being restricted to test a specific unit - not a whole chain of code.
Most people need to try this for them selves in order to really see the benefits. Do it. You will not regret it.Article created: Aug 10 at 10:45. Edited Sep 18 at 09:54.
Monday, September 21, 2015
Dependency injection in C# - a simple introduction
Are you sure? ....
Subscribe to:
Post Comments
(
Atom
)
No comments :
Post a Comment