【问题标题】:Unity 2.0 IOC with Entity FrameworkUnity 2.0 IOC 与实体框架
【发布时间】:2011-10-29 02:57:45
【问题描述】:

我在我的项目中使用 Unity 2.0 和 asp.net mvc3。当我尝试在 Repository 类中配置 TestEntities : ObjectContext 时引发异常。

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>

【问题讨论】:

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


    【解决方案1】:

    这是完全错误的配置。首先,您使用的是每个线程的生命周期。每个线程的生命周期适用于您自己控制线程但在 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>
    

    【讨论】:

    • 非常感谢。您能否给我更多有关“处理上下文处置”的信息。
    • 您只需要在不再需要上下文时处理它,并且因为上下文应该只用于单个逻辑操作(工作单元),所以它可能很频繁。例如,在 Web 应用程序或 Web 服务中,每个请求通常只有一个上下文。在表单应用程序中,您可以为每个表单或演示者拥有一个上下文。
    • 谢谢。如果您有时间检查另一个问题,我真的很感激:link
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    • 1970-01-01
    • 2017-07-07
    相关资源
    最近更新 更多