我在项目中使用Unity 2.0和asp.net mvc3。当我尝试在TestEntities : ObjectContext
类中配置Repository
时抛出异常。
public class UserRepository:IUser
{
//TestEntities ctx = new TestEntities();
[Dependency]
public TestEntities ctx { get; set; }
//...
}
这是异常消息:
TestEntities类型有多个长度为1的构造函数。无法消除歧义。
XML配置:
<?xml version="1.0" encoding="utf-8" ?>
<unity xmlns="schemas.microsoft.com/practices/2010/unity">
<container>
<register type="DomainModel.Entity.TestEntities, DomainModel"
mapTo="DomainModel.Entity.TestEntities, DomainModel">
<lifetime type="perthread"/>
</register>
<register type="DomainModel.Abstract.IUser, DomainModel"
mapTo="DomainModel.Concrete.UserRepository, DomainModel">
<lifetime type="perthread"/>
</register>
</container>
</unity>
答案 0 :(得分:3)
这是完全错误的配置。首先,您使用的是每线程生命周期。每个线程的生命周期适用于您自己控制线程的情况,但在ASP.NET MVC中您没有这样的控制。 ASP.NET MVC在内部使用线程池,因此线程可以重用于后续请求=您的上下文将在请求之间重用,它将导致您a lot of problems。另一个问题是上下文的每个线程的生命周期will not handle disposal,所以除非你自己处理它(如果你没有在你的控制下没有线程生命周期,这是相当困难的)你的应用程序将满足大内存泄漏。
您必须使用不同的生命周期管理:
Resolve
时都会创建新实例,但在依赖关系层次结构中,相同的实例将用于所有注入。你必须自己处理上下文。Resolve
时,都会创建新实例。如果在依赖关系层次结构中需要多次实例,它将为每次注入创建一个新实例。你必须自己处理上下文。Resolve
时,都将使用相同的实例。完成请求后,您必须处置子容器,并且所有具有分层生命周期的实例也将被处置。有关不同终身经理的更多信息,请参见my article。
解决TestEntities
课程的问题。默认情况下,Unity会尝试使用具有最大参数数量的构造函数,并使用依赖项注入来解析这些参数。如果它会找到多个这样的构造函数,它将抛出此错误,因为它不知道选择哪一个。即使只有一个你也会得到错误,因为这样的构造函数的依赖关系将无法解决。您必须明确告诉Unity您要调用哪个构造函数。这个将强制Unity使用默认构造函数:
<register type="DomainModel.Entity.TestEntities, DomainModel"
mapTo="DomainModel.Entity.TestEntities, DomainModel">
<lifetime type="perresolve"/>
<constructor />
</register>