Nie jestem ekspertem, ale myślę, że mogę pomóc. I tak, jest to szczególny rodzaj wstrzykiwania zależności.
Oświadczenie: Prawie wszystko zostało „skradzione” z Wiki Ninject
Przeanalizujmy pomysł wstrzykiwania zależności, przechodząc przez prosty przykład. Załóżmy, że piszesz następną hitową grę, w której szlachetni wojownicy walczą o wielką chwałę. Po pierwsze, potrzebujemy broni odpowiedniej do uzbrojenia naszych wojowników.
class Sword
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
Następnie stwórzmy klasę reprezentującą samych naszych wojowników. Aby zaatakować wrogów, wojownik będzie potrzebował metody Attack (). Po wywołaniu tej metody powinien użyć Miecza, aby uderzyć przeciwnika.
class Samurai
{
readonly Sword sword;
public Samurai()
{
this.sword = new Sword();
}
public void Attack(string target)
{
this.sword.Hit(target);
}
}
Teraz możemy stworzyć naszych samurajów i walczyć!
class Program
{
public static void Main()
{
var warrior = new Samurai();
warrior.Attack("the evildoers");
}
}
Jak możesz sobie wyobrazić, to wydrukuje Wytnij złoczyńców do połowy na konsoli. Działa to dobrze, ale co, jeśli chcielibyśmy uzbroić naszego Samuraja w inną broń? Ponieważ Miecz jest tworzony wewnątrz konstruktora klasy Samuraj, musimy zmodyfikować implementację klasy, aby dokonać tej zmiany.
Kiedy klasa jest zależna od konkretnej zależności, mówi się, że jest ściśle powiązana z tą klasą . W tym przykładzie klasa samurajów jest ściśle powiązana z klasą miecza. Gdy klasy są ściśle powiązane, nie można ich zamieniać bez zmiany ich implementacji. Aby uniknąć ścisłego łączenia klas, możemy użyć interfejsów, aby zapewnić poziom pośredni. Stwórzmy interfejs reprezentujący broń w naszej grze.
interface IWeapon
{
void Hit(string target);
}
Następnie nasza klasa Sword może wdrożyć ten interfejs:
class Sword : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
I możemy zmienić naszą klasę samurajów:
class Samurai
{
readonly IWeapon weapon;
public Samurai()
{
this.weapon = new Sword();
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Teraz nasz samuraj może być uzbrojony w inną broń. Ale poczekaj! Miecz wciąż powstaje w konstruktorze Samuraja. Ponieważ wciąż musimy zmienić implementację Samuraja, aby dać naszemu wojownikowi kolejną broń, Samuraj jest nadal ściśle związany z Mieczem.
Na szczęście istnieje łatwe rozwiązanie. Zamiast tworzyć Miecz z konstruktora Samuraja, możemy go odsłonić jako parametr konstruktora. Znany również jako wstrzykiwanie konstruktora.
class Samurai
{
readonly IWeapon weapon;
public Samurai(IWeapon weapon)
{
this.weapon = weapon;
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Jak zauważył Giorgio, istnieje również zastrzyk nieruchomości. To byłoby coś w stylu:
class Samurai
{
IWeapon weapon;
public Samurai() { }
public void SetWeapon(IWeapon weapon)
{
this.weapon = weapon;
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Mam nadzieję że to pomoże.