抽象基本クラスから Service Locator を削除しようとしていますが、何に置き換えればよいかわかりません。ここに私が持っているものの疑似例があります:
public abstract class MyController : Controller
{
protected IKernel kernel;
public MyController(IKernel kernel) { this.kernel = kernel); }
protected void DoActions(Type[] types)
{
MySpecialResolver resolver = new MySpecialResolver(kernel);
foreach(var type in types)
{
IMyServiceInterface instance = resolver.Get(type);
instance.DoAction();
}
}
}
これに関する問題MySpecialResolver
は、派生クラスのインスタンシエーターが、カーネルが例外をスローしないようにするために必要なバインディングを認識していないことです。
ここからどのタイプを解決しなければならないかわからないため、これは本質的に扱いにくいかもしれません。派生クラスはtypes
パラメーターの作成を担当しますが、どこにもハードコーディングされていません。(型は、派生クラスの構成階層の奥深くにある属性の存在に基づいています。)
遅延読み込みデリゲートでこれを修正しようとしましたが、これまでのところ明確な解決策は思いつきませんでした。
アップデート
ここには実際には 2 つの問題があります。1 つは、IoC コンテナーがコントローラーに渡され、サービス ロケーターとして機能することです。これは簡単に削除できます。あらゆる種類の手法を使用して、コール スタックの上下に位置を移動できます。
2 番目の問題は難しい問題です。要件が実行時まで公開されない場合、コントローラーに必要なサービスがあることをどのように保証できるでしょうか。最初から明らかだったはずです。サービスロケータの状態またはコレクションの内容に常に依存します。この特定のケースでは、静的に型付けされた依存関係に関するこの記事で説明されている問題をいくらいじっても解決しません。私が最終的にやろうとしているのは、Lazy 配列をコントローラー コンストラクターに渡し、必要な依存関係が欠落している場合は例外をスローすることだと思います。