Não sou especialista, mas acho que posso ajudar. E sim, é um tipo específico de injeção de dependência.
Isenção de responsabilidade: quase tudo isso foi "roubado" do Ninject Wiki
Vamos examinar a idéia de injeção de dependência, percorrendo um exemplo simples. Digamos que você esteja escrevendo o próximo jogo de grande sucesso, onde nobres guerreiros lutam por grande glória. Primeiro, precisaremos de uma arma adequada para armar nossos guerreiros.
class Sword
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
Então, vamos criar uma classe para representar nossos próprios guerreiros. Para atacar seus inimigos, o guerreiro precisará de um método Attack (). Quando esse método é chamado, ele deve usar sua espada para golpear seu oponente.
class Samurai
{
readonly Sword sword;
public Samurai()
{
this.sword = new Sword();
}
public void Attack(string target)
{
this.sword.Hit(target);
}
}
Agora, podemos criar nosso Samurai e lutar!
class Program
{
public static void Main()
{
var warrior = new Samurai();
warrior.Attack("the evildoers");
}
}
Como você pode imaginar, isso imprimirá Chopped the evildoers limpo ao meio no console. Isso funciona muito bem, mas e se quiséssemos armar nosso Samurai com outra arma? Como o Sword é criado dentro do construtor da classe Samurai, precisamos modificar a implementação da classe para fazer essa alteração.
Quando uma classe depende de uma dependência concreta, diz-se que ela está fortemente acoplada a essa classe . Neste exemplo, a classe Samurai está fortemente acoplada à classe Sword. Quando as classes são fortemente acopladas, elas não podem ser trocadas sem alterar sua implementação. Para evitar o acoplamento de classes, podemos usar interfaces para fornecer um nível de indireção. Vamos criar uma interface para representar uma arma em nosso jogo.
interface IWeapon
{
void Hit(string target);
}
Então, nossa classe Sword pode implementar esta interface:
class Sword : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
E podemos alterar nossa classe Samurai:
class Samurai
{
readonly IWeapon weapon;
public Samurai()
{
this.weapon = new Sword();
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Agora nosso Samurai pode estar armado com armas diferentes. Mas espere! A espada ainda é criada dentro do construtor do Samurai. Como ainda precisamos alterar a implementação do Samurai para dar ao nosso guerreiro outra arma, o Samurai ainda está fortemente acoplado ao Sword.
Felizmente, existe uma solução fácil. Em vez de criar a espada de dentro do construtor de Samurai, podemos expô-la como um parâmetro do construtor. Também conhecida como Injeção de Construtor.
class Samurai
{
readonly IWeapon weapon;
public Samurai(IWeapon weapon)
{
this.weapon = weapon;
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
Como Giorgio apontou, também há injeção de propriedade. Isso seria 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 isto ajude.