No soy un experto, pero creo que puedo ayudar. Y sí, es un tipo específico de inyección de dependencia.
Descargo de responsabilidad: Casi todo esto fue "robado" de Ninject Wiki
Examinemos la idea de la inyección de dependencia siguiendo un ejemplo simple. Digamos que estás escribiendo el próximo juego de gran éxito, donde los guerreros nobles luchan por la gran gloria. Primero, necesitaremos un arma adecuada para armar a nuestros guerreros.
class Sword
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
Entonces, creemos una clase para representar a nuestros propios guerreros. Para atacar a sus enemigos, el guerrero necesitará un método Attack (). Cuando se llama a este método, debe usar su Espada para golpear a su oponente.
class Samurai
{
readonly Sword sword;
public Samurai()
{
this.sword = new Sword();
}
public void Attack(string target)
{
this.sword.Hit(target);
}
}
¡Ahora podemos crear nuestro Samurai y luchar!
class Program
{
public static void Main()
{
var warrior = new Samurai();
warrior.Attack("the evildoers");
}
}
Como puede imaginar, esto imprimirá Chopped the evildoers por la mitad en la consola. Esto funciona bien, pero ¿y si quisiéramos armar a nuestro Samurai con otra arma? Dado que la Espada se crea dentro del constructor de la clase Samurai, tenemos que modificar la implementación de la clase para hacer este cambio.
Cuando una clase depende de una dependencia concreta, se dice que está estrechamente vinculada a esa clase . En este ejemplo, la clase Samurai está estrechamente unida a la clase Espada. Cuando las clases están estrechamente acopladas, no pueden intercambiarse sin alterar su implementación. Para evitar un acoplamiento estrecho de clases, podemos usar interfaces para proporcionar un nivel de indirección. Creemos una interfaz para representar un arma en nuestro juego.
interface IWeapon
{
void Hit(string target);
}
Entonces, nuestra clase Sword puede implementar esta interfaz:
class Sword : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
Y podemos alterar nuestra clase de Samurai:
class Samurai
{
readonly IWeapon weapon;
public Samurai()
{
this.weapon = new Sword();
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Ahora nuestro Samurai puede estar armado con diferentes armas. ¡Pero espera! La espada todavía se crea dentro del constructor de Samurai. Como todavía necesitamos alterar la implementación de Samurai para darle a nuestro guerrero otra arma, Samurai todavía está estrechamente unido a Sword.
Afortunadamente, hay una solución fácil. En lugar de crear la Espada desde dentro del constructor de Samurai, podemos exponerla como un parámetro del constructor. También conocido como inyección de constructor.
class Samurai
{
readonly IWeapon weapon;
public Samurai(IWeapon weapon)
{
this.weapon = weapon;
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Como señaló Giorgio, también hay inyección de propiedades. Eso sería algo como:
class Samurai
{
IWeapon weapon;
public Samurai() { }
public void SetWeapon(IWeapon weapon)
{
this.weapon = weapon;
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Espero que esto ayude.