NInjectを使用して(シングルトンスコープの)Fooサービスの既知の固定リストを解決しようとしています。この解決は、FooProviderのコンストラクターで行われます。問題は、各Fooにもこのプロバイダーが必要になることです。
public interface IFoo { }
public interface IFooProvider { }
public class Foo : IFoo
{
private readonly IFooProvider _provider;
public Foo(IFooProvider provider)
{
_provider = provider;
}
}
public class FooProvider : IFooProvider
{
private List<IFoo> _allFooServices;
public FooProvider(IKernel kernel)
{
_allFooServices = kernel.GetAll<IFoo>().ToList();
}
}
public class Program
{
private static void Main(string[] args)
{
var IoC = new StandardKernel();
IoC.Bind<IFoo>().To<Foo>().InSingletonScope();
IoC.Bind<IFooProvider>().To<FooProvider>().InSingletonScope();
var foo = IoC.Get<IFoo>();
}
}
ここには論理的な循環ループがあり、明らかにスタックオーバーフローはそれが下がっていることを示しています。ただし、両方のインターフェイスをシングルトンにバインドしています。
それについて考える; IFooを解決しようとしますが、IFooProviderの解決が必要であり、それ自体にIFooのリストが必要です...しかし、まだ解決しようとしているため、IFooシングルトンについてはまだ解決していません。
では、どうすればこれを回避できますか?
[編集]可能な解決策; IFooサービスインスタンスのバッファリングを遅らせます。
public FooProvider(IKernel kernel)
{
_kernel = kernel;
}
public IFoo Find(object context)
{
if (_allFooServices == null)
_allFooServices = _kernel.GetAll<IFoo>().ToList();
return _allFooServices.Where(...
[なぜ?]
一般的な考え方は、アンチパターンとして説明されているように、サービスロケーターパターンを回避することです。したがって、実行時に依存性注入を介してサービスを解決しようとするのではなく、セットアップ中にサービスのリストを取得しようとします。ただし、これに伴う問題は、サービスのいずれかが他のサービスを見つけたい場合、上記の問題があることです。