1

IServiceLocator使用HierarchicalLifetimeManager.

我所看到的表明 UnityUnityServiceLocator在您注册具体类型时将其视为一种特殊情况。它将类型视为静态单例,即使它不应该这样做。这种行为似乎对UnityServiceLocator.

背景:我正在逐步淘汰ServiceLocator我们代码中存在的几个地方的“静态”。第一步是IServiceLocator在 Unity 中注册,然后将其作为依赖项注入到使用它的那些类中。

在下面的代码中,我注册了一个注入工厂来创建一个新的UnityServiceLocator. 我还将其范围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实例并写出控制台输出三次,每个容器一次。它没有——它只做了一次,就好像我把它注册为一个单例一样:

使用容器调用的 InjectionFactory:20903718

情况变得更糟:

如果我现在让我自己的类实现IServiceLocator(从字面上看,实现接口,一个接受 的 ctor IUnityContainer,并让所有方法都 throw NotImplementedException),然后换行

     return new UnityServiceLocator(c);

     return new MyUnityServiceLocator(c);

这开始表现出我期望的方式:

InjectionFactory invoked with container: 20903718 
InjectionFactory invoked with container: 51746094 
InjectionFactory invoked with container: 41215084

UnityServiceLocator除非 Unity 将其视为特殊情况,否则我无法理解这种行为。有没有人对这种行为有任何其他解释?我是否遗漏了一些明显的东西,还是 Unity 在内部将 UnityServiceLocator 视为一种特殊情况并忽略了我指定的生命周期策略?

4

1 回答 1

1

事实证明这UnityServiceLocator是一种特殊情况——它在第一次创建时在自己的构造函数中注册ExternallyControlledLifetimeManager

有关更多信息,请参阅 Randy Levy 的评论:unity.codeplex.com/workitem/12727

于 2013-03-19T08:43:19.463 回答