IServiceLocator
を使用して登録および解決するときに、Unity で予期しない動作が見られHierarchicalLifetimeManager
ます。
私が見ているのは、具体的な型UnityServiceLocator
を登録するときに、Unity が具体的な型を特別なケースとして扱うことを示唆しています。型を静的シングルトンとして扱うべきではない場合でも扱います。この動作は に特有のようUnityServiceLocator
です。
ServiceLocator
背景:コード内のいくつかの場所で「静的」が存在する場合は、「静的」を段階的に廃止しています。最初のステップはIServiceLocator
、Unity に登録し、それを使用するクラスに依存関係として注入することでした。
次のコードでは、インジェクション ファクトリを登録して、 の新しいインスタンスを作成しますUnityServiceLocator
。また、子コンテナーごとに 1 つのインスタンスを与えるためにスコープを設定しHierarchicalLifetimeManager
ます。
private static void Main(string[] args)
{
var container = new UnityContainer();
container.RegisterType<IServiceLocator>(
new HierarchicalLifetimeManager(),
new InjectionFactory(
c =>
{
Console.WriteLine("InjectionFactory invoked with container: " + c.GetHashCode());
return new UnityServiceLocator(c);
}));
container.Resolve<IServiceLocator>(); // expect to see console output here
container.Resolve<IServiceLocator>(); // don't expect to see console output here
var child = container.CreateChildContainer();
child.Resolve<IServiceLocator>(); // expect to see console output here
container.Resolve<IServiceLocator>(); // don't expect to see console output here
var anotherChildContainer = container.CreateChildContainer();
anotherChildContainer.Resolve<IServiceLocator>(); // expect to see console output here
anotherChildContainer.Resolve<IServiceLocator>(); // don't expect to see console output here
}
UnityServiceLocator
上記のコードは、ファクトリを呼び出し、インスタンスを作成し、コンソール出力を 3 回 (コンテナーごとに 1 回) 書き出すことを期待しています。そうではありません-シングルトンとして登録したかのように、一度実行します。
コンテナーで呼び出された InjectionFactory: 20903718
ひどくなる:
自分のクラスを実装し(文字通り、インターフェイスを実装し、 を受け取り、すべてのメソッドに throw を持たせるIServiceLocator
1 つの ctor を実装する)、行を入れ替えるとします。IUnityContainer
NotImplementedException
return new UnityServiceLocator(c);
と
return new MyUnityServiceLocator(c);
これは私が期待するように動作し始めます:
InjectionFactory invoked with container: 20903718
InjectionFactory invoked with container: 51746094
InjectionFactory invoked with container: 41215084
Unity がUnityServiceLocator
特別なケースとして扱わない限り、この動作を理解できません。この動作について他に説明がある人はいますか? 明らかな何かが欠けていますか、それとも Unity が内部的に UnityServiceLocator を特別なケースとして扱い、指定しているライフタイム戦略を無視していますか?