初心者向けのDIおよびIoC

DI / IoCのトピックは非常にシンプルですが、それがどのように機能し、なぜWebでそれが必要なのかを説明するのは非常に困難です。 これがUnityを使用した私の試みです。 トピックが十分に説明されているかどうかは、判断するのはあなた次第です。


簡単な例を作成しましょう:

// . -
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/>
このコードには1つの問題がありますMyServiceクラスはMyServiceクラスにあまりにも結びついています。 これは悪いので


つまり、問題はoperator new()です。 依存関係を適切に制御し、単独でオブジェクトをテストできるようにするには、この演算子を拒否する必要があります。

どうやって? これがまさにIoCおよびDIパターンの機能です。 IoC(制御の反転)は、オブジェクトの制御(この場合はオブジェクトの有効期間)がコンポーネントに割り当てられるパターンです。 何らかのアウトソーシング-オブジェクトを自分で作成する代わりに( new() )、いわゆるオブジェクトにリクエストします。 IoCコンテナー、つまり、有能なオブジェクトを生成できる工場。

確かに、コンテナからオブジェクトのコピーを要求するたびに遅延が発生します。 これらの場合、別のパターンを使用できます。 DI(Dependency Injection)により、初期化中に必要な依存関係をコンテナーから自動的にプルできます。 つまり、IoCコンテナーを介してMyWindowを作成すると、DIメカニズムは、直接関与することなくMyServiceを魔法のように初期化できます。

どのように機能しますか?


プログラムにはUnityフレームワークを使用します。 開始するには、 Main()書き換えます。その中にコンテナを作成し、DIをウィンドウに適用します。

public class MyProgram<br/>
{<br/>
static void Main()<br/>
{<br/>
⋮<br/>
var uc = new UnityContainer(); <br/>
Application.Run( uc.Resolve<MyWindow>() );<br/>
}<br/>
}<br/>
コンテナのResolve()メソッドを使用して、タイプMyWindowオブジェクトの作成だけでなく、 そのすべての依存関係の自動作成も要求します。 ここで、サービス(つまり、依存する部分)の作成を自動的に取得する方法を見てみましょう。 まず、サービスインターフェイスを引き出して、後で変更できるようにします。

interface IService<br/>
{<br/>
void DoSomething();<br/>
}<br/>
<br/>
public class MyService : IService<br/>
{<br/>
//
}<br/>
次に、インターフェースが使用されるようにMyWindowを変更します。 コンテナが初期化するように、サービスへのリンクを追加する方法にはいくつかのオプションがあります。 それらの1つを次に示します。

public class MyWindow : Form<br/>
{<br/>
private IService service;<br/>
public MyWindow(IService service)<br/>
{<br/>
this .service = service;<br/>
}<br/>
}<br/>
あと1つだけ残っていることがありますIService型のオブジェクトのリクエストでIServiceIServiceようにコンテナにIServiceします。

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/>
それだけです!!! これで、プログラムが起動すると、変数serviceウィンドウが自動的に初期化されます 。 これは、コンストラクター注入と呼ばれます。 コンストラクターを空のままにしたいですか? お願い:

public class MyWindow : Form<br/>
{<br/>
[Dependency]<br/>
public IService Service { get; set; }
<br/>
<br/>
public MyWindow()<br/>
{<br/>
⋮<br/>
}<br/>
}<br/>
フィールドをプロパティに変更し、 [Dependency]属性でマークして、クラスを作成するときに初期化する必要があることをコンテナに示唆しました。 結果は、コンストラクターの場合と同じです。 この手法は「セッター注入」と呼ばれます。

以上です! ご清聴ありがとうございました! トピックに興味があり、サンクトペテルブルクに住んでいる場合は、明日の会議に来てください。

シリーズのパート2を読む

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


All Articles