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视为特殊情况而忽略了我指定的生命周期策略?
事实证明UnityServiceLocator
是一个特殊情况-它在第一次创建时在自己的构造函数中向ExternallyControlledLifetimeManager
注册本身。
更多信息请参阅Randy Levy的评论:unity.codeplex.com/workitem/12727