Non sono un esperto, ma penso di poter aiutare. E sì, è un tipo specifico di iniezione di dipendenza.
Disclaimer: quasi tutto questo è stato "rubato" dal Wiki Ninject
Esaminiamo l'idea dell'iniezione di dipendenza attraverso un semplice esempio. Diciamo che stai scrivendo il prossimo gioco di successo, in cui i nobili guerrieri combattono per la grande gloria. Innanzitutto, avremo bisogno di un'arma adatta per armare i nostri guerrieri.
class Sword
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
Quindi, creiamo una classe per rappresentare i nostri guerrieri stessi. Per attaccare i suoi nemici, il guerriero avrà bisogno di un metodo Attack (). Quando viene chiamato questo metodo, dovrebbe usare la sua Spada per colpire il suo avversario.
class Samurai
{
readonly Sword sword;
public Samurai()
{
this.sword = new Sword();
}
public void Attack(string target)
{
this.sword.Hit(target);
}
}
Ora possiamo creare il nostro samurai e combattere!
class Program
{
public static void Main()
{
var warrior = new Samurai();
warrior.Attack("the evildoers");
}
}
Come puoi immaginare, questo stampa i malfattori tritati a metà sulla console. Funziona bene, ma se volessimo armare il nostro Samurai con un'altra arma? Poiché la spada viene creata all'interno del costruttore della classe Samurai, dobbiamo apportare modifiche all'implementazione della classe per poter apportare questa modifica.
Quando una classe dipende da una dipendenza concreta, si dice che sia strettamente accoppiata a quella classe . In questo esempio, la classe Samurai è strettamente accoppiata alla classe Sword. Quando le classi sono strettamente accoppiate, non possono essere scambiate senza alterarne l'implementazione. Al fine di evitare le classi strettamente accoppiate, possiamo usare le interfacce per fornire un livello di riferimento indiretto. Creiamo un'interfaccia per rappresentare un'arma nel nostro gioco.
interface IWeapon
{
void Hit(string target);
}
Quindi, la nostra classe Sword può implementare questa interfaccia:
class Sword : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
E possiamo modificare la nostra classe Samurai:
class Samurai
{
readonly IWeapon weapon;
public Samurai()
{
this.weapon = new Sword();
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Ora il nostro Samurai può essere armato con diverse armi. Ma aspetta! La spada è ancora creata all'interno del costruttore di Samurai. Dato che dobbiamo ancora modificare l'implementazione del Samurai per dare al nostro guerriero un'altra arma, il Samurai è ancora strettamente accoppiato alla Spada.
Fortunatamente, esiste una soluzione semplice. Invece di creare la Spada dall'interno del costruttore di Samurai, possiamo invece esporla come parametro del costruttore. Conosciuto anche come Iniezione Costruttore.
class Samurai
{
readonly IWeapon weapon;
public Samurai(IWeapon weapon)
{
this.weapon = weapon;
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Come ha sottolineato Giorgio, c'è anche un'iniezione di proprietà. Sarebbe qualcosa del tipo:
class Samurai
{
IWeapon weapon;
public Samurai() { }
public void SetWeapon(IWeapon weapon)
{
this.weapon = weapon;
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Spero che sia di aiuto.