1

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 を持たせるIServiceLocator1 つの ctor を実装する)、行を入れ替えるとします。IUnityContainerNotImplementedException

     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 を特別なケースとして扱い、指定しているライフタイム戦略を無視していますか?

4

1 に答える 1

1

これはUnityServiceLocator特殊なケースであることがわかります。最初に作成されたときに、独自のコンストラクターに登録されます。ExternallyControlledLifetimeManager

詳細については、Randy Levy のコメント ( unity.codeplex.com/workitem/12727)を参照してください。

于 2013-03-19T08:43:19.463 に答える