asp.net mvc 应用程序中的工作单元模式
Posted
技术标签:
【中文标题】asp.net mvc 应用程序中的工作单元模式【英文标题】:The unit of work pattern within a asp.net mvc application 【发布时间】:2009-12-30 19:07:47 【问题描述】:我一直在看这个优秀的blog,标题为“NHibernate 和工作单元模式”,并且有一个关于在 asp.net mvc 项目中使用 UnitOfWork.Start 的最佳位置的问题。
我的 SLN 分为以下几个项目:-
MVC project
Repository
NHibernateUnitOfWork
我有一个界面:-
public interface INameRepository
...
IList<Name> GetByOrigin(int OriginId)
...
我有一个具体的实现
public class NameRepository : INameRepository
...
public IList<Name> GetByOrigin(int OriginId)
using (UnitOfWork.Start())
var query = session.Linq<...
return query;
...
我的问题是我是否使用 using(UnitOfWork.Start()) 将我的所有方法包装在我的所有存储库中,还是有更好的方法?
我正在使用 nHibernate、asp.net mvc。
【问题讨论】:
【参考方案1】:使用工作单元模式,您不必将每个数据访问方法都放在一个单独的工作单元中。您围绕需要完成的整个工作使用工作单元,在大多数情况下,在 Web 应用程序中是一个 webrequest。这个想法是请求可以失败或成功。当您在一个请求期间向数据库添加 2 个项目时,应该同时添加或不添加。不只是其中之一。在大多数情况下,在 mvc(或其他 Web)应用程序中启动工作单元的最简单方法是使用 global.asax 的 begin 和 end 请求方法
class Global
BeginRequest()
servicelocater.get<unitofwork>().start();
EndRequest()
var unit = servicelocater.Get<Unitofwork>();
try
unit.commit();
catch
unit.rollback();
throw;
class Repository<T>
public Repository(INHibernateUnitofwork unitofwork)
this.unitofwork = unitofwork;
public void Add(T entity)
unitofwork.session.save(entity);
【讨论】:
谢谢,这是最好的方法。只需要整理是否有活动事务并刷新它。谢谢【参考方案2】:我认为 Sharp Architecture 很好地解决了这个问题。他们所做的是将工作单元放入 ASP .Net MVC 动作过滤器中。基本上您可以定义一个事务操作过滤器,例如
public class TransactionAttribute : ActionFilterAttribute
public override void OnActionExecuting(ActionExecutingContext filterContext)
UnitOfWork.Start();
public override void OnActionExecuted(ActionExecutedContext filterContext)
UnitOfWork.Stop();
并在您的控制器类中将 Transaction 属性放在您的 Action Result 方法上
【讨论】:
这种方法的一个缺点是每个子控制器/渲染动作都在一个单独的工作单元中以上是关于asp.net mvc 应用程序中的工作单元模式的主要内容,如果未能解决你的问题,请参考以下文章
在 ASP.NET MVC 3 中的多个服务之间共享一个工作单元
MVC3 EF 工作单元 + 通用存储库 + Ninject