// . -
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 becauseMyWindow
to write a unit test for MyWindow
in isolation from MyService
. In fact, you get an integration test.MyService
with OtherService
unless OtherService
from it. If several classes depend on MyService
, you will have to change them all.operator new()
. In order to competently control dependencies and allow ourselves to test objects in isolation, this operator must be abandoned.new()
) we request it from the so-called. IoC container, that is, the factory, which is able to competently produce objects.MyWindow
through the IoC container, the DI mechanism will magically be able to initialize MyService
without our direct participation.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).Source: https://habr.com/ru/post/62830/
All Articles