Unity 2.0 IOC与实体框架

时间:2011-10-29 02:57:46

标签: entity-framework inversion-of-control unity-container

我在项目中使用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>

1 个答案:

答案 0 :(得分:3)

这是完全错误的配置。首先,您使用的是每线程生命周期。每个线程的生命周期适用于您自己控制线程的情况,但在ASP.NET MVC中您没有这样的控制。 ASP.NET MVC在内部使用线程池,因此线程可以重用于后续请求=您的上下文将在请求之间重用,它将导致您a lot of problems。另一个问题是上下文的每个线程的生命周期will not handle disposal,所以除非你自己处理它(如果你没有在你的控制下没有线程生命周期,这是相当困难的)你的应用程序将满足大内存泄漏。

您必须使用不同的生命周期管理:

  • Per-resolve:每次在容器上调用Resolve时都会创建新实例,但在依赖关系层次结构中,相同的实例将用于所有注入。你必须自己处理上下文。
  • 瞬态:每次拨打Resolve时,都会创建新实例。如果在依赖关系层次结构中需要多次实例,它将为每次注入创建一个新实例。你必须自己处理上下文。
  • 分层:您必须为每个请求处理创建新的子容器并解析此子容器上的实例。每次在该子容器实例上调用Resolve时,都将使用相同的实例。完成请求后,您必须处置子容器,并且所有具有分层生命周期的实例也将被处置。
  • 自定义生命周期管理器,如this per-request example但具有正确的依赖注入配置,这不应该是必需的,每个解析或分层管理器应该解决您的所有要求。

有关不同终身经理的更多信息,请参见my article

解决TestEntities课程的问题。默认情况下,Unity会尝试使用具有最大参数数量的构造函数,并使用依赖项注入来解析这些参数。如果它会找到多个这样的构造函数,它将抛出此错误,因为它不知道选择哪一个。即使只有一个你也会得到错误,因为这样的构造函数的依赖关系将无法解决。您必须明确告诉Unity您要调用哪个构造函数。这个将强制Unity使用默认构造函数:

<register type="DomainModel.Entity.TestEntities, DomainModel"
          mapTo="DomainModel.Entity.TestEntities, DomainModel">
    <lifetime type="perresolve"/>
    <constructor />
</register>