MVC 3、Unity 2 - 每个请求生命周期管理器
我正在使用 http://unitymvc3.codeplex.com/ 上的 Unity MVC3 代码来进行 NHibernate 会话我的 IUnitOfWork 的每个请求实例。
它在几周前开始工作,我做了一些更改,现在我的 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));
}
从我的 Application_Start()
调用 ConfigureUnity()
这是我的 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...但代码可以工作,因此它以某种方式注册/拉动对象,使其表现静态。
I'm using the Unity MVC3 code at http://unitymvc3.codeplex.com/ to have a NHibernate session per request instance of my IUnitOfWork.
It was working a few weeks ago, I've made some changes, and now my IUnitOfWork appears to have a static lifetime.
From my 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()
is called from my Application_Start()
Heres me test code from my HomeController constructor:
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;
}
... the IUnitOfWork is resolved to the same instance, however, on subsequent page requests, a new IUnitOfWork is not created... but the code works, so its somehow registering / pulling the object so that it acts static.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会完全摆脱 IUnitOfWorkFactory 并将 IUnitOfWork 注入到您的控制器中 - 前提是您只需要每个请求一个工作单元,这似乎是合乎逻辑的。然后,您将更多地利用 IoC 容器的功能,而不仅仅是将其用作服务定位器。
只需将 HomeController 构造函数更改为:
如果您还没有这样做,
请在调用 DependencyResolver.SetResolver 之前
添加:当 MVC 核心尝试实例化您的控制器时,它将使用 Unity.MVC3 解析器,该解析器将自动满足其中的任何依赖项这种情况意味着工作单元。
Unity.MVC3 解析器还将在请求结束时自动处理您的工作单元。
I would get rid of the IUnitOfWorkFactory altogether and just inject IUnityOfWork into your controller - providing that you only ever want one unit of work per request which seems logical. You are then utilising the power of the IoC container more and not just using it as a service locator.
Just change your HomeController constructor to:
And if you have not already done so, add:
before you call DependencyResolver.SetResolver
When the MVC core tries to instantiate your controller, it will use the Unity.MVC3 resolver which will automatically satisfy any dependencies which in this case means the unitOfWork.
The Unity.MVC3 resolver will also automatically take care of disposing your unit of work at the end of the request.
看起来您希望 UnitOfWorkFactory 返回您的 IUnitOfWork 依赖项?似乎您应该使用 .RegisterFactory 来实现此目的。您可以使用 ContainerControlledLifetimeManager 注册工厂,它将表现为“单例”,而无需求助于静态成员。
对于 WCF(可能还有 Web)来说,生命周期管理可能会有点棘手。我已经使用本文中的代码有一段时间了。它将 Unity 生命周期完美地映射到 WCF 请求生命周期...它可能会给您一些关于如何最好地实现目标的想法。
http://drewdotnet.blogspot.com/2009/07 /unity-lifetime-managers-and-wcf.html
It looks like you want the UnitOfWorkFactory to return your IUnitOfWork dependencies? Seems like you should be using .RegisterFactory to achieve this. You can register the factory with a ContainerControlledLifetimeManager, and it will behave as a "singleton" without resorting to a static member.
Lifetime management can get a bit tricky with WCF (and probably web). I have been using the code from this article for quite a while. It perfectly maps Unity lifetime to WCF request lifetime... It may give you some ideas about how to best achieve your aim.
http://drewdotnet.blogspot.com/2009/07/unity-lifetime-managers-and-wcf.html