私は専門家ではありませんが、私は助けることができると思います。そして、はい、それは依存性注入の特定のタイプです。
免責事項:これのほとんどすべてが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");
}
}
ご想像のとおり、これにより、Chopped the evildoersが半分になってコンソールに表示されます。これはうまく機能しますが、サムライを別の武器で武装させたい場合はどうでしょうか?SwordはSamuraiクラスのコンストラクター内で作成されるため、この変更を行うにはクラスの実装を変更する必要があります。
クラスが具体的な依存関係に依存している場合、そのクラスに密結合していると言われます。この例では、SamuraiクラスはSwordクラスと密結合しています。クラスが密結合されている場合、実装を変更せずにクラスを交換することはできません。クラスの密結合を回避するために、インターフェイスを使用して、間接的なレベルを提供できます。ゲームの武器を表すインターフェースを作成しましょう。
interface IWeapon
{
void Hit(string target);
}
次に、Swordクラスでこのインターフェイスを実装できます。
class Sword : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
そして、Samuraiクラスを変更できます。
class Samurai
{
readonly IWeapon weapon;
public Samurai()
{
this.weapon = new Sword();
}
public void Attack(string target)
{
this.weapon.Hit(target);
}
}
今、私たちのサムライはさまざまな武器で武装することができます。ちょっと待って!ソードはまだサムライのコンストラクター内で作成されます。戦士に別の武器を与えるために、サムライの実装を変更する必要があるため、サムライは依然としてソードと密結合しています。
幸いなことに、簡単な解決策があります。SamuraiのコンストラクターからSwordを作成するのではなく、代わりにコンストラクターのパラメーターとして公開できます。コンストラクターインジェクションとも呼ばれます。
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);
}
}
お役に立てれば。