LightInject IoC コンテナhttp://www.lightinject.net/を試すと、タイプ ISomeService を解決するときに stackoverflow 例外がスローされます。
すべてのタイプが App_Start に登録されています。
container.RegisterAssembly("MyApp*.dll");
そして、コントローラーで解決しようとすると失敗し、stackoverflow 例外がスローされます。
public SomeController(ISomeService someService)
{
_someService = someService;
}
ServiceLocator を使用すると、同じエラーが発生します。
ServiceLocator.Current.GetInstance<ISomeService>();
追跡したところ、LightInject ServiceContainer クラスで失敗していることがわかりますが、まだ失敗する理由はわかりません。
public object GetInstance(Type serviceType)
{
return GetDefaultDelegate(serviceType, true)(constants.Items);
}
GetDefaultDelegate を呼び出した後、実行パスは再び GetInstance で終了し、無限ループとスタック オーバーフローが発生します。
EDIT 2 - これをさらに追跡したところ、コンストラクターとプロパティ注入の両方を同時に持つ SomeService が原因のようです:
public class SomeService : ISomeService
{
public IAnotherService AnotherService { get; set; }
public SomeService(IAnotherService anotherService)
{
AnotherService = anotherService;
}
}
依存関係 IAnotherService AnotherService は、コンストラクターとプロパティを介して注入されていますが、プロパティ インジェクターを使用する意図はありませんでした。
編集3
アプリには ServiceLocator を使用するレイヤーがいくつかあるため、最初に NuGet を使用して LI を独自のプロジェクトに追加しました。
MyApp.IoC.LightInject
MyApp.Repositories
MyApp.Services
MyApp.Web.UI
ただし、サービス ロケーター プロバイダーは UI レイヤーで設定できるため、実際には独自のプロジェクトに追加する必要はありません。
var serviceLocator = new LightInjectServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);
そのため、余分なプロジェクトを削除し、代わりに NuGet パッケージを UI レイヤーに配置しました。LightInject.Annotation もインストールし、container.EnableAnnotatedPropertyInjection() メソッドを意図的に呼び出さないようにして、コンストラクター インジェクションのみが使用されるようにしました。まだスタックオーバーフローをスローしています。
解決が機能しているかどうかをテストするために、 HomeController.Index() メソッドでこれを実行しています。
public ActionResult Index()
{
var a = ServiceLocator.Current.GetInstance<ISomeService>();
}
コンソール ロギングを ServiceController.GetInstance メソッドに追加して、stackoverflow の原因となったメソッド呼び出しの流れを確認できるようにしました。これはログであり、結果は少し予想外です。ISomeService の CreateDelegate() を呼び出すと、最初に HomeController のインスタンスを取得しようとすることがわかります。なぜでしょうか?
DoGetInstance: ISomeService. Key = ''
GetInstance: ISomeService
TryGetValue: ISomeService not found
TryAddValue: trying to add ISomeService now
CreateDynamicMethodDelegate: ISomeService
CreateDynamicMethodDelegate: calling CreateDelegate() for ISomeService
DoGetInstance: HomeController. Key = ''
GetInstance: HomeController
TryGetValue: HomeController not found
TryAddValue: trying to add HomeController now
CreateDynamicMethodDelegate: HomeController
CreateDynamicMethodDelegate: calling CreateDelegate() for HomeController
DoGetInstance: ISomeService. Key = ''
GetInstance: ISomeService
TryGetValue: ISomeService not found
TryAddValue: trying to add ISomeService now
CreateDynamicMethodDelegate: ISomeService
CreateDynamicMethodDelegate: calling CreateDelegate() for ISomeService
DoGetInstance: HomeController. Key = ''
GetInstance: HomeController
TryGetValue: HomeController not found
TryAddValue: trying to add HomeController now
CreateDynamicMethodDelegate: HomeController
CreateDynamicMethodDelegate: calling CreateDelegate() for HomeController
DoGetInstance: ISomeService. Key = ''
GetInstance: ISomeService
TryGetValue: ISomeService not found
TryAddValue: trying to add ISomeService now
CreateDynamicMethodDelegate: ISomeService
CreateDynamicMethodDelegate: calling CreateDelegate() for ISomeService
DoGetInstance: HomeController. Key = ''
GetInstance: HomeController
TryGetValue: HomeController not found
TryAddValue: trying to add HomeController now
CreateDynamicMethodDelegate: HomeController
CreateDynamicMethodDelegate: calling CreateDelegate() for HomeController
DoGetInstance: ISomeService. Key = ''
GetInstance: ISomeService
TryGetValue: ISomeService not found
TryAddValue: trying to add ISomeService now
CreateDynamicMethodDelegate: ISomeService
CreateDynamicMethodDelegate: calling CreateDelegate() for ISomeService
サービスのコンストラクターをコメント アウトすると、解決が機能し、すべての依存関係がプロパティ インジェクションによって解決されます。コンストラクターが含まれている場合、stackoverflow 例外がスローされます。
ISomeService の解決はプロパティのみを使用する場合に機能しますが、そのサービスの依存関係に ISomeService が含まれている場合、IAnotherService を解決できません。上記のログが問題を明らかにすることを願っています。これまでのところ、LightInject のパフォーマンスは Unity よりも大幅に優れています