Unity在手动注册UnityServiceLocator时不尊重HierarchicalLifetimeManager

本文关键字:HierarchicalLifetimeManager UnityServiceLocator 注册 Unity | 更新日期: 2023-09-27 18:03:59

在使用HierarchicalLifetimeManager注册和解析IServiceLocator时,我在Unity中看到一些意想不到的行为。

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

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

在下面的代码中,我注册了一个注入工厂来创建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(字面上,实现接口,一个接受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视为特殊情况而忽略了我指定的生命周期策略?

Unity在手动注册UnityServiceLocator时不尊重HierarchicalLifetimeManager

事实证明UnityServiceLocator是一个特殊情况-它在第一次创建时在自己的构造函数中向ExternallyControlledLifetimeManager注册本身

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

相关文章:
  • 没有找到相关文章