7

私はIOCとUnityに関するいくつかの記事を読んだことがあり、混乱しました:(

それで、基本に戻って、誰かが以下のコードが何をするのか教えてもらえますか?

private IStudent _student;
public HomeController(IStudent student)
{
     _student= student;
}

public interface IStudent 
{
     // Some method
}

Itz Basicですが、素人の視点から理解しようとしています。上記のコードは正確には何をしますか?

4

4 に答える 4

23

HomeControllerは、Studentクラスに何らかの責任を委任するため、Studentに依存しています。

実装する1つの方法は次のとおりです。

public HomeController()
{
    private Student _student;
    public HomeController()
    {
        _student = new Student();
    }
}
public class Student 
{
    // Some method
}

しかし、HomeControllerはStudentクラスに強く依存しています。Studentの他の実装を使用したい場合(たとえば、HomeControllerの単体テスト中にStudentをモックしたい場合)はどうなりますか。StudentクラスまたはHomeControllerクラスを変更する必要があります(または他のあまり良くないオプションを使用する必要があります)。これは、HomeControllerがStudentクラスに緊密に結合されていることを意味します。

もう1つの方法は、投稿したコードです。

public class HomeController
{
    private IStudent _student;
    public HomeController(IStudent student)
    {
        _student = student;
    }
}
public interface IStudent
{
    // Some method
}
public class Student : IStudent
{
    // Implementation of some method
}

ここでは、IStudentの任意の実装を渡すことができます。つまり、単体テストではIStudentのモックオブジェクトを渡すことができ、実際のコードではStudentクラスのオブジェクトを渡すことができます。そのため、HomeControllerは、Studentクラス(実装)ではなく、IStudentインターフェイス(抽象化)に依存するようになりました。これは、OOPの原則に沿ったものです。

実装ではなく、インターフェースへのプログラム。

抽象化に依存します。具体的なクラスに依存しないでください。

また、ソフト依存関係になりました。もはやStudentクラスと緊密に結合されていません。緩く結合されています。これで、通常、HomeControllerをインスタンス化するときにIStudentのどの実装を渡す必要があるかを心配する必要はありません。これは、正しいインターフェイスとクラスを登録している限り、Depedency Injection Container(この場合はUnity)が処理するものです。

_container.Register<IStudent, Student>();

したがって、HomeControllerの新しいインスタンスが必要な場合、コンテナーはIStudentのインスタンスが必要であることを識別します。そのため、IStudentの登録済みインスタンスをインスタンス化し、HomeControllerクラスをインスタンス化するときにパラメーターとして渡します。

また、参照しているのは「依存性注入」(IoCの特定の形式の1つ)であることに注意してください。IoCには他の形式もあります(コールバック、オブザーバーパターンなど)。

編集: DIの人気記事 を読むことを忘れないでください。

于 2013-03-11T06:42:47.193 に答える
2

IoCでは、インターフェイスと、インターフェイスを実装しているクラスを登録する必要があります。したがって、登録すると、上記のような署名がある場合は常に、IoCはIStudentが実装されたクラスのインスタンスを自動的に作成し、コントローラーの初期化中にそれをオブジェクトに注入します。これにより、メンバーを宣言する時間と労力を節約できます。上記の場合、宣言するのは1つだけですが、それはもっと多くなる可能性があり、それらすべてがコントローラーに渡すためにさらにいくつかのインスタンスを必要とする可能性があります。それらをすべて正しく登録すると、IoCはその後その作業を行います。実際、注入されたメンバーのスコープ/ライフタイムを決定できます。PerInstance / PerRequest/またはSingletonにすることができます。

どちらを使用したいかは、節約可能なIoCフレームワークを利用できます。

于 2013-03-11T06:10:23.750 に答える
2

一般に、これはクラスの依存関係の注入と呼ばれ、クラスについて考えるか、正確には(ユーザー入力の検証、データベースとの調整、HTML出力の生成など)のようなすべてのものを処理するGODクラスであるため、すべてのコードを保持します。単一の場所、または単一のクラスを使用してすべてのソフトウェアを開発していると言えますが、それは良いことではありませんか?

答えはあなたが物事を整理する方法に依存します、あなたはそれが属する場所で物事を整理することはあなたが上記の神のクラスで問題を見るよりも有益であると思いますか?

したがって、OOPSに関しては、単一のクラスshdには変更する理由が1つありますが、サービスの助けを借りるよりも、作業を完了する必要があります。

そして、あなたのHomeControllerは、過労を望まないので同じことをしています。それは、Studentオブジェクトにstudentを処理するように要求しました。

于 2013-03-11T06:11:09.803 に答える
1

新しいHomeControllerオブジェクトがIOCリゾルバーによって構築されると、コンストラクターを介してIOCコンテナー(登録したもの)によって提供されるIStudentインターフェイスを実装するオブジェクトを取得します。

コンストラクタインジェクションについて詳しくは、こちらをご覧ください。

于 2013-03-11T06:15:37.683 に答える