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の人気記事
を読むことを忘れないでください。