4

アプリケーションで依存性注入を処理するために Autofac を使用しています。すべての登録を明示的に行う必要がないように、最初に使用RegisterAssemblyTypes().AsImplementedInterfaces()してから、特別に構成する必要があるものだけを処理します。

いくつかの異なる実装を持つという名前のインターフェイスがIToolStripPopulatorあり、そのうちのいくつかは使用されていますが、一部はもう使用されていません (私はしっかりと動作し、OCP に準拠しようとしているため、通常、別の機能が必要な場合はそれらを変更しません) 、むしろそれらをそのままにして、今必要なことを行う新しいものを作成します)。そのため、次の 2 つの方法でインターフェイスの自動登録を上書きする必要があります。

  • 1 つの実装はメイン ロジックに挿入され、他のいくつかの実装のデコレータとして機能します。As<IToolStripPopulator>()これは、アプリケーションの機能が現在依存している実装であるため、当然、これを介して登録し、それを使用して実行したいと考えています。
  • これらの他の実装は、そのデコレータ クラス内でのみ使用される「内部」ポピュレータです。それらを注入するには、次の 2 つの方法があります。
    • 特定の型を使用して外部実装のコンストラクターを明示的に接続します。また、そのコンストラクターは、私が現在使用している正確な数の内部ポピュレーターを取得する必要があり、OCP に準拠していないため、これはあまり良くありません。
    • 外側の実装にIEnumerable<IToolStripPopulator>;を取らせます。これは私がやりたいことですが、行き詰まっているところでもあります。

AutofacIEnumerableだけでそれを解決することはできません。インターフェイスのすべての実装を解決してしまうからです。解決中に無限ループが発生する可能性があります)。

だから私がやりたいことはこれです:

// the inner populators
builder.RegisterType<BrowsersMenuPopulator>().Named<IToolStripPopulator>("inner");
builder.RegisterType<ThreadsafeConnectionMenuPopulator>().Named<IToolStripPopulator>("inner");

// the decorator implementation
builder.RegisterType<BrowserAndConnectionMenuPopulator>().As<IToolStripPopulator>().WithParameter( ? );

しかし、その時点で既存の登録に実際にアクセスする方法はありません。

4

2 に答える 2

7

....そしてここで、実際に動作するとは思っていなかったもう 1 つのことを試しましたが、動作しました。

builder.Register(c => c.ResolveNamed<IEnumerable<IToolStripPopulator>>("inner")).As<IEnumerable<IToolStripPopulator>>();

IEnumerable<IToolStripPopulator>私が予想したように、 「inner」という名前の登録を解決しようとはしませんが、 「inner」という名前IEnumerableの登録の解決を試みますIToolStripPopulator- まさに私がそれを必要としているのです。

これは、それ以上の構成なしで登録するだけで、正しく解決され、デコレータの実装に挿入されAs<IToolStripPopulator>()ます。

正式な観点からは、デコレーター登録で直接解決する名前を指定できる方がより直感的で柔軟になるため (複数の解決が必要な場合はどうすればよいでしょうかIEnumerable<IToolStripPopulator>?)、実際にはこれを使用することをお勧めしますが、多くの場合、これは次のようにする必要があります。足りる。

@codinghorror の「ゴム製のアヒルの問題解決」の概念は、私の毎日の仕事を支配しています....

于 2012-06-16T02:28:18.140 に答える
0

私が知っていることを直接指定する唯一の方法は、登録コードで直接「更新」することです。

//decorator impl
builder.Register(c => new BrowserAndConnectionMenuPopulator(c.ResolveNamed<IEnumerable<IToolStripPopulator>>("inner"),...)).As<IToolStripPopulator>();

これには、登録で必要な依存関係を直接指定できるという利点がありますが、依存関係を再構成する際の柔軟性が失われるというデメリットがありますBrowserAndConnectionMenuPopulator。完全を期すためにこれを含めましたが、正直なところ、私はあなたが発見した解決策を好みます。

于 2012-06-27T15:11:15.107 に答える