📜 ⬆️ ⬇️

DI and IoC for beginners

The topic of DI / IoC is quite simple, but it is very difficult to find a good description of how it works and why it is needed on the network. Here is my attempt using Unity. Is the topic well explained - to judge you.


Let's create a simple example:

// . -
public class MyService<br/>
{<br/>
public MyService()<br/>
{<br/>
â‹®<br/>
}<br/>
public void DoSomething()<br/>
{<br/>
â‹®<br/>
}<br/>
}<br/>
<br/>
// . -
public class MyWindow : Form<br/>
{<br/>
private MyService service;<br/>
public MyWindow()<br/>
{<br/>
service = new MyService();<br/>
}<br/>
}<br/>
<br/>
//
public class MyProgram<br/>
{<br/>
static void Main()<br/>
{<br/>
â‹®<br/>
///
Application.Run( new MyWindow);<br/>
}<br/>
}<br/>
There is one problem in this code: the MyWindow class MyWindow too tightly bound to the MyService class. This is bad because
')

In short, our problem is operator new() . In order to competently control dependencies and allow ourselves to test objects in isolation, this operator must be abandoned.

How? This is exactly what the IoC and DI patterns do. IoC (Inversion of Control) is a pattern in which the control of an object (in our case, the lifetime of an object) is assigned to some component. Some kind of such an outsourcing - instead of creating an object by ourselves (through new() ) we request it from the so-called. IoC container, that is, the factory, which is able to competently produce objects.

True, every time asking for a copy of the object from the container is lazy. In these cases, we can use another pattern. DI (Dependency Injection) allows us to automatically pull out the dependencies we need during initialization from the container. That is, when we create MyWindow through the IoC container, the DI mechanism will magically be able to initialize MyService without our direct participation.

How it works?


Let's use the Unity framework for our program. To begin with, let's rewrite Main() - create a container in it and apply DI to our window:

public class MyProgram<br/>
{<br/>
static void Main()<br/>
{<br/>
â‹®<br/>
var uc = new UnityContainer(); <br/>
Application.Run( uc.Resolve<MyWindow>() );<br/>
}<br/>
}<br/>
With the container's Resolve() method, we request not only the creation of an object of type MyWindow , but also the automatic creation of all its dependencies . Now let's look at how you can get the creation of a service (i.e. the dependent part) automatically. First, let's pull out the service interface so that it can be changed later:

interface IService<br/>
{<br/>
void DoSomething();<br/>
}<br/>
<br/>
public class MyService : IService<br/>
{<br/>
â‹® //
}<br/>
Now we change MyWindow to use the interface. There are several options for how to add a link to the service so that the container initializes it. Here is one of them:

public class MyWindow : Form<br/>
{<br/>
private IService service;<br/>
public MyWindow(IService service)<br/>
{<br/>
this .service = service;<br/>
}<br/>
}<br/>
Now it remains to do only one thing - to tell the container that, upon request of objects of type IService it MyService :

public class MyProgram<br/>
{<br/>
static void Main()<br/>
{<br/>
â‹®<br/>
var uc = new UnityContainer();<br/>
uc.RegisterType<IService, MyService>(); <br/>
Application.Run(uc.Resolve<MyWindow>());<br/>
}<br/>
}<br/>
That's all!!! Now when the program is started, the service window variable will be initialized automatically . This is called “constructor injection”. Want to leave the constructor empty? You are welcome:

public class MyWindow : Form<br/>
{<br/>
[Dependency]<br/>
public IService Service { get; set; }
<br/>
<br/>
public MyWindow()<br/>
{<br/>
â‹®<br/>
}<br/>
}<br/>
By changing the field to a property and marking it with the [Dependency] attribute, we hinted to the container that it needed to be initialized when creating the class. The result is the same as with the constructor. This technique is called “injection into a property” (setter injection).

That's all! Thanks for attention! If you are interested in the topic and you live in Petersburg, come to us tomorrow for a meeting .

Read the 2nd part of the series

Source: https://habr.com/ru/post/62830/


All Articles