最近,我开始深入研究Repository Patterns和UnitOfWork的概念,并探索EntityFramework。
基于MVC示例制作了我自己的实现,他们从Controller中处理UnitOfWork,如下所示:
protected override void Dispose(bool disposing)
{
unitOfWork.Dispose();
base.Dispose(disposing);
}
我根本没有进入MVC,也不是Webforms中的新手,但我认为他们正在重写Controller dispose方法,以便将UnitOfWork处理为“其他所有内容”。
基本上我想在我的ASP.NET WebForms网站中实现相同的概念,并将页面代码后面使用的UnitOfWork与处理页面本身一起处理。
我考虑过从生命周期中添加相同的 Page_Unload 事件,但我不确定这是否是正确的方法,因为我之前没有搞过这些事情。我的想法如下:
protected void Page_Unload(object sender, EventArgs e)
{
unitOfWork.Dispose();
base.Dispose();
}
我如何安全地实现这一目标,我是否走在正确的轨道上?
答案 0 :(得分:4)
首先:不要发明轮子。
使用依赖注入框架,例如: StructureMap,Ninject,Unity等......
您的 UoW 应该在请求开始时启动 ,请求时 。
换句话说:EF的DataContext应该在请求启动时初始化。然后你可以将它存储在某个地方(Session,...),它可以被重用于该请求。 每个请求的一个DataContext实例。
但是如果你自己尝试这样做,那么你使用依赖注入框架就会出错,会让它变得如此简单。
框架可以处理DataContext的生命周期(UoW)。
答案 1 :(得分:2)
您应该将软件划分为图层和组件......
用户界面 - >控制器 - >服务 - > DAL
E.g。
UI.Submit - > Controller.SaveUserInfo - > UsersManagementService.SaveUserInfo - >
public void SaveUserInfo(User user)
{
using (var uow = new Uow())
{
var dbUser = uow.Users.GetByKey(user.Id);
if (dbUser == null)
{
// TODO:
}
dbUser.Name = user.Name;
dbUser.Address = user.Address;
// Or use a framework for injecting properties
uow.SaveAndAcceptChanges();
}
}
您甚至可以在certiain服务方法中接收查询逻辑,例如
public User GetUsersMatching(Func<IQueryable<User>, IQueryable<User>> query)
{
using (var uow = new Uow())
{
var users = query(uow.Users).ToList();
return users;
// For this to work using POCOs you may need to disable proxy creation
}
}
但是,这使得测试变得更加复杂,并且要求服务的消费者理解LINQ to Entities的限制和最佳实践。
我还建议不要使用纯学术存储库 - 每个基础类型模式,因为有效经常使用来自相同域需要交叉的不同类型的数据存储库“在LINQ中查询并要求join
子句,或者将多个查询的结果组合在一起并重新整形,然后将其作为一个干净的结果返回。
相反,将您的服务视为domain-speicifc-repositories,您可以在其中获得各种类型的输出。或者换句话说,在您的MVC下使用SOA并在您的EF之上。