给出以下两个接口(interface)和一个类:
interface IRepository<T> {}
interface IXRepository : IRepository<MyType> {}
class XRepository : IXRepository {}
我想要一个 XRepository
类型的单例可以通过 IRepository<MyType>
解决或 IXRepository
.
我从以下代码开始:
public void Register<TFrom, TTo>(params Type[] typesToRegister) where TTo : TFrom
{
parentContainer.RegisterType<TFrom, TTo>(new HierarchicalLifetimeManager());
foreach (Type type in typesToRegister)
{
parentContainer.RegisterType(type, typeof(TTo), new HierarchicalLifetimeManager(), new InjectionFactory(c => c.Resolve<TFrom>()));
}
}
这是客户端方法调用:
service.Register<IRepository<MyType>, XRepository>(typeof(IXRepository));
执行此语句后的 childContainer 的注册(标题:RegisteredType、MappedToType、Name 和 LifetimeManagerType):
-
typeof(IRepository<MyType>)
,typeof(XRepository>)
,null
,typeof(HierarchicalLifetimeManager)
-
typeof(IXRepository)
,typeof(XRepository)
,null
,typeof(HierarchicalLifetimeManager)
但是如果我尝试通过 IRepository<MyType>
来解决(或 IXRepository
),将抛出 StackOverflowException。这是因为 new InjectionFactory(c => c.Resolve<TFrom>())
中的 lambda 表达式被一次又一次地执行。
有谁知道引擎盖下发生了什么?请求 IRepository<MyType>
时执行 lambda 表达式的原因是什么? ?
我发现如果你在注册时提供了一个名字(在这个例子中是“gaga”),不会抛出 StackOverflowException:
-
typeof(IRepository<MyType>)
,typeof(XRepository>)
, <强>"gaga"
,typeof(HierarchicalLifetimeManager)
-
typeof(IXRepository)
,typeof(XRepository)
,null
,typeof(HierarchicalLifetimeManager)
谢谢, 罗杰
最佳答案
您可以将具体类型 XRepository
注册为单例,然后注册要使用该类型解析的两个接口(interface):
container.RegisterType<XRepository>(new HierarchicalLifetimeManager());
container.RegisterType<IRepository<String>, XRepository>();
container.RegisterType(typeof(IXRepository), typeof(XRepository));
如果运行以下代码,您将看到应用了单例行为并考虑了子容器:
var isSingleton = container.Resolve<IRepository<String>>() == container.Resolve<IXRepository>();
var outerInstance = container.Resolve<IXRepository>();
using(var childContainer = container.CreateChildContainer())
{
isSingleton = childContainer.Resolve<IRepository<String>>() == childContainer.Resolve<IXRepository>();
var isHierarchichalSingleton = outerInstance != childContainer.Resolve<IXRepository>();
}
附带说明一下,您的问题可以通过更简单的方式重现。 这可能是 Unity 中的一个错误 这是根据 Unity 的设计(检查@Lukazoid 评论和回答),例如:
interface IFoo { }
interface IBar { }
class Foo : IFoo, IBar { }
container.RegisterType<IFoo, Foo>();
container.RegisterType<IBar, Foo>(new InjectionFactory(c => c.Resolve<IFoo>()));
var foo = container.Resolve<IFoo>();
关于c# - 统一: Will get a StackOverflowException if I try to get a singleton that is registered in multiple mappings,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30502431/