14

Ninject のような DI フレームワークが基本を超えてどのように動くかを「理解」するには、もう少し助けが必要です。

Ninject サンプルを取得します。

class Samurai {
private IWeapon _weapon;

    [Inject]
    public Samurai(IWeapon weapon) {
      _weapon = weapon;
    }

    public void Attack(string target) {
      _weapon.Hit(target);
    }
 }

DI フレームワーク (つまり、上記の [Inject] 参照) がなければ、参照クラスは次のようになります。

class Program {
   public static void Main() { 
    Samurai warrior1 = new Samurai(new Shuriken());
    Samurai warrior2 = new Samurai(new Sword());
    warrior1.Attack("the evildoers");
    warrior2.Attack("the evildoers");
  }
}

...すべてを新しくしている場所。はい、Samurai で依存関係を削除しましたが、チェーンの 1 ステップ上の依存関係を取得しました。単純。

Ninject を使用すると、次の方法ですべてを新しくする必要がなくなります。

class Program {
  public static void Main() {
    IKernel kernel = new StandardKernel(new WarriorModule());
    Samurai warrior = kernel.Get<Samurai>();
    warrior.Attack("the evildoers");
  }
}

ただし、これは私の混乱の領域です: 適用可能なカーネルとモジュール (つまり .IoC.TypeResolver.Get<>()) を効率的に更新するために何らかのサービス ロケーターを作成せずに、どこでもカーネルを新しくする必要はありません(サービスロケーターはどこでも参照しますか?)、そしてb)さらに重要なことに、独自の依存関係を持つ依存関係を持つ大きな長いチェーンがある場合、インジェクションをずっと渡すという極端な方法を取ります私が確信しているのは、深刻なアンチパターンです (友人はそれを「ホットポテト依存性注入」アンチパターンと呼んでいました)。

言い換えれば、DI フレームワークの魔法の 1 つは、依存関係をチェーンのずっと上に挿入し続ける必要がないことだと思いました (つまり、コンストラクターに 10 個のパラメーターを含む最初の参照で、いずれも関係がありません)。チェーンに沿ってはるかに遠くまで何か)-依存関係がチェーンの上下に継続的に参照されたり、サービスロケーターの参照がいたるところに広がったりしないように、私の混乱に対する魔法または解決策はどこにありますか.

私にとってさらに混乱しているのは、DIフレームワークを使用している場合、参照されるクラスが通常コンストラクターに配置されるIList(つまり、新しいReferencedClass(myList))を必要とするシナリオに対処する最良の方法は何ですか?文字列データベース接続文字列のような単純なケースでは、飛びません。プロパティを作成して、新規作成/DI フレームワーク サービスの検索後に設定するだけですか? いえ

var referencedClass = IoC.Get<IReferencedClass>();
referencedClass.MyList = myList;

全体として、これは受け取った後に恥ずかしくなる可能性が高い投稿だと思いますが、今のところ、最善のアプローチを決定しようとして何度も壁に頭をぶつけてしまいました.

4

1 に答える 1

3

「ホットポテト」の依存関係の問題に関しては、これは発生する必要はありません。依存性注入フレームワークがこれを処理します。

たとえば、Class1 が Class2 に依存しており、Class2 が Class3 に依存している場合、Class2 の依存関係に対応するために Class3 を Class1 に注入する必要はありません。Class1 を要求すると、カーネルは依存チェーンをたどり、ダウンストリームの依存関係を自動的に解決します (実行中のすべてのクラスがカーネルに登録されている場合)。

Class1 依存 Class2 依存 Class3

Class1 コンストラクターは、Class3 について言及する必要はまったくありません。

2番目の問題については、これがどのように、またはどのように対応されるかは、フレームワークに依存します。Bind().To().WithConstructorArgument()Ninject では、構文を使用して新しい List アイテムをコンストラクターに提供できると思います。

于 2010-01-03T00:00:41.017 に答える