MVC 3,Unity 2 - 按要求终身经理

时间:2011-06-15 19:55:12

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

我在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 ......但是代码可以工作,所以它以某种方式注册/拉动对象以使其静态行动。

2 个答案:

答案 0 :(得分:2)

我会完全摆脱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解析器还会在请求结束时自动处理您的工作单元。

答案 1 :(得分:0)

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

使用WCF(可能还有Web),终身管理可能会有点棘手。我一直在使用本文中的代码。它完美地将Unity生命周期映射到WCF请求生命周期......它可以为您提供有关如何最好地实现目标的一些想法。

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