Я не експерт, але думаю, що можу допомогти. І так, це специфічний тип введення залежностей.
Відмова: Майже все це було "вкрадено" у Ninject Wiki
Розглянемо ідею введення залежності, пройшовши простий приклад. Скажімо, ви пишете чергову гру-блокбастер, де шляхетні воїни ведуть битву за велику славу. По-перше, нам знадобиться зброя, придатна для озброєння наших воїнів.
class Sword
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
Тоді давайте створимо клас для представлення самих наших воїнів. Для того, щоб напасти на його ворогів, воїну знадобиться метод Attack (). Коли цей метод викликається, він повинен використовувати свій Меч для удару по противнику.
class Samurai
{
readonly Sword sword;
public Samurai()
{
this.sword = new Sword();
}
public void Attack(string target)
{
this.sword.Hit(target);
}
}
Тепер ми можемо створити наш самурай і вести бій!
class Program
{
public static void Main()
{
var warrior = new Samurai();
warrior.Attack("the evildoers");
}
}
Як ви можете собі уявити, це надрукує Нарізані злодії чисто навпіл до консолі. Це працює чудово, але що робити, якщо ми хотіли озброїти свого самурая іншою зброєю? Оскільки Меч створений всередині конструктора класу Samurai, ми повинні модифікувати реалізацію класу, щоб внести цю зміну.
Коли клас залежить від конкретної залежності, він вважається тісно пов'язаним з цим класом . У цьому прикладі клас Самурай щільно поєднаний з класом Меч. Коли заняття щільно з'єднані, їх не можна міняти, не змінюючи їх виконання. Щоб уникнути щільно з'єднаних класів, ми можемо використовувати інтерфейси для забезпечення рівня непрямості. Давайте створимо інтерфейс, щоб представити зброю в нашій грі.
interface IWeapon
{
void Hit(string target);
}
Тоді наш клас Sword може реалізувати цей інтерфейс:
class Sword : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
І ми можемо змінити наш клас самураїв:
class Samurai
{
readonly IWeapon weapon;
public Samurai()
{
this.weapon = new Sword();
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Тепер наш самурай може бути озброєний різною зброєю. Але зачекайте! Меч все ще створюється всередині конструктора Самураїв. Оскільки нам ще потрібно змінити реалізацію Самураїв, щоб дати нашому воїну ще одну зброю, Самурай все ще міцно поєднаний з Мечем.
На щастя, є просте рішення. Замість того, щоб створювати Меч всередині конструктора Самураїв, ми можемо викласти його як параметр конструктора. Також відомий як інжекція конструктора.
class Samurai
{
readonly IWeapon weapon;
public Samurai(IWeapon weapon)
{
this.weapon = weapon;
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Як зазначив Джорджіо, також існує ін'єкція властивості. Це було б щось на зразок:
class Samurai
{
IWeapon weapon;
public Samurai() { }
public void SetWeapon(IWeapon weapon)
{
this.weapon = weapon;
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Сподіваюся, це допомагає.