【问题标题】:MVC 3, Unity 2 - Per Request Lifetime ManagerMVC 3,Unity 2 - 每个请求生命周期管理器
【发布时间】:2011-09-15 20:25:45
【问题描述】:

我使用 http://unitymvc3.codeplex.com/ 的 Unity MVC3 代码为我的 IUnitOfWork 的每个请求实例创建一个 NHibernate 会话。

几周前它还在工作,我做了一些更改,现在我的 IUnitOfWork 似乎有一个静态的生命周期。

来自我的 global.asax.cs:

private static IUnitOfWorkFactory _UoWFactory = new UnitOfWorkFactory(Enums.Databases.MyDBName)
                                                            .AddMapping<DepartmentMap>()
                                                            .CompleteConfiguration();

/// <summary>
/// Configure Unity Application Block
/// </summary>
private void ConfigureUnity()
{
    CIUnity.UnityContainer.Container = new UnityContainer()
        .RegisterType(typeof(IRepository<>), typeof(Repository<>))
        .RegisterType<IUnitOfWork, UnitOfWork>(Enums.Databases.MyDBName.ToString(), new HierarchicalLifetimeManager(), new InjectionConstructor(Enums.Databases.MyDBName))
        .RegisterInstance<IUnitOfWorkFactory>(Enums.Databases.MyDBName.ToString(), _UoWFactory);

    DependencyResolver.SetResolver(new UnityDependencyResolver(CIUnity.UnityContainer.Container));
}

ConfigureUnity() 是从我的Application_Start() 调用的

这是我的 HomeController 构造函数中的测试代码:

private IUnitOfWork uow;
private IUnitOfWork uow2;

public HomeController()
{
    uow = CIUnity.Container.Resolve<IUnitOfWork>(Enums.Databases.MyDBName.ToString());
    IRepository<Employee> repo = uow.GetRepository<Employee>();

    uow2 = CIUnity.Container.Resolve<IUnitOfWork>(Enums.Databases.MyDBName.ToString());
    IRepository<Department> deptrepo = uow2.GetRepository<Department>();

    var q = from a in repo.Find()
            select a;

    var d = from b in deptrepo.Find()
            select b;
}

... IUnitOfWork 被解析为同一个实例,但是,在随后的页面请求中,没有创建新的 IUnitOfWork...但是代码可以工作,因此它以某种方式注册/拉取对象,使其行为静态。

【问题讨论】:

    标签: asp.net-mvc-3 unity-container lifetime object-lifetime


    【解决方案1】:

    我将完全摆脱 IUnitOfWorkFactory 并将 IUnityOfWork 注入您的控制器 - 前提是您只需要每个请求一个工作单元,这似乎是合乎逻辑的。然后,您将更多地利用 IoC 容器的功能,而不仅仅是将其用作服务定位器。

    只需将您的 HomeController 构造函数更改为:

    public HomeController(IUnitOfWork unitOfWork)
    {
      IRepository<Employee> repo = unitOfWork.GetRepository<Employee>();
    
      IRepository<Department> deptrepo = unitOfWork.GetRepository<Department>();
    
      ...
    }
    

    如果您还没有这样做,请添加:

    CIUnity.Container.RegisterControllers();
    

    在调用 DependencyResolver.SetResolver 之前

    当 MVC 核心尝试实例化您的控制器时,它将使用 Unity.MVC3 解析器,该解析器将自动满足任何依赖关系,在这种情况下意味着 unitOfWork。

    Unity.MVC3 解析器还将在请求结束时自动处理您的工作单元。

    【讨论】:

    • 感谢您的意见。我在工厂背后的原因是因为我们可能需要每个请求有多个工作单元/ISessions(每个数据库一个) - 因此命名注册 IUnitOfWork 背后的原因。我的最终计划是将 IService 对象从业务层注入到控制器中。
    • @Chris - 我看不出工厂是如何在代码示例中使用的。控制器构造函数只是通过静态容器解析存储库。有什么遗漏吗?
    【解决方案2】:

    您似乎希望 UnitOfWorkFactory 返回您的 IUnitOfWork 依赖项?似乎您应该使用 .RegisterFactory 来实现这一点。您可以使用 ContainerControlledLifetimeManager 注册工厂,它​​将表现为“单例”,而无需借助静态成员。

    使用 WCF(可能还有 Web)进行生命周期管理可能会有些棘手。我使用这篇文章中的代码已经有一段时间了。它完美地将 Unity 生命周期映射到 WCF 请求生命周期...它可能会为您提供一些关于如何最好地实现目标的想法。

    http://drewdotnet.blogspot.com/2009/07/unity-lifetime-managers-and-wcf.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多