JMc*_*JMc 6 repository layer unit-of-work isession
使用工作单元/存储库模式构建了一个小应用程序后,我很难理解如何在我的业务层中正确使用它.我的应用程序有一个数据访问层,可以是NHibernate或实体框架.我可以轻松地在这些之间切换.
我有许多存储库,例如,客户,订单等.我的工作单元将是一个ISession或一个对象上下文,具体取决于我想要测试的DAL.
我的业务层包含一个业务方法 - CreateOrder().我正在努力理解的是,在业务层中我应该初始化我的工作单元和我的存储库.
专注于Nhibernate,我的DAL看起来像:
public class NHibernateDAL : IUnitOfWork
{
log4net.ILog log = log4net.LogManager.GetLogger(typeof(NHibernateDAL));
ISession context;
public NHibernateDAL()
{
context = SessionProvider.OpenSession();
this.Context.BeginTransaction();
CurrentSessionContext.Bind(context);
}
public ISession Context
{
get { return context; }
}
public void Commit()
{
this.Context.Transaction.Commit();
context.Close();
}
public void Dispose()
{
ISession session = CurrentSessionContext.Unbind(SessionProvider.SessionFactory);
session.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
在我的业务层中,我想知道我应该在哪里声明我的工作单元和存储库.它们是在类级别还是在CreateOrder方法中声明的?
例如:
public class BusinessLogic
{
UnitOfWork _unitOfWork = new UnitOfWork(NHibernateDAL);
NhRepository<Order> _orderRepository = new NhRepository<Order>(_unitOfWork);
NhRepository<Customer> _customerRepository = new NhRepository<Customer>(_unitOfWork);
....
public void CreateOrder(.....)
{
Order order = new Order();
_orderRepository.Add(order);
_unitOfWork.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码仅在第一次调用CreateOrder()方法时起作用,但不适用于后续调用,因为会话已关闭.我已经尝试在提交事务后删除'context.Close()'调用,但这也失败了.虽然上述方法不起作用,但使用此范围声明我的存储库和工作单元似乎更为正确.
但是,如果我按照下面的方式实现它,它可以正常工作,但在方法本身的范围内声明存储库和工作单元似乎不自然.如果我有一吨商业方法,那么我将在整个地方宣布存储库和工作单元:
public class BusinessLogic
{
public void CreateOrder(.....)
{
UnitOfWork _unitOfWork = new UnitOfWork(NHibernateDAL);
var _orderRepository = new NhRepository<Order>(_unitOfWork);
NhRepository<Customer> _customerRepository = null;
Order order = new Order();
_orderRepository.Add(order);
_unitOfWork.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我要用类级别声明来实现它,那么我认为我需要一些方法在CreateOrder方法的开头重新打开相同的工作单元.
在业务层中使用工作单元和存储库的正确方法是什么?
在我看来你几乎已经明白了。在我们的新服务器堆栈中,我有这样的设置:
WCF Service Layer --> just returns results from my Business Layer
My business layer is called, creates a unitofwork, creates the respository
Calls the respository function
Uses AutoMapper to move returned results into a DTO
My repository gets the query results and populates a composite object.
Run Code Online (Sandbox Code Playgroud)
看起来几乎就像你那里的东西。虽然我们使用Unity来定位你所谓的业务层。(我们称之为函数处理器)
不过,我强烈建议您不要将工作单元保留在班级级别。毕竟每个谨慎的函数都是一个工作单元。所以我的是这样的(为了保护无辜者,名字已被更改):
using ( UnitOfWorkScope scope = new UnitOfWorkScope( TransactionMode.Default ) )
{
ProcessRepository repository = new ProcessRepository( );
CompositionResultSet result = repository.Get( key );
scope.Commit( );
MapData( );
return AutoMapper.Mapper.Map<ProcessSetDTO>( result );
}
Run Code Online (Sandbox Code Playgroud)
我们还就何时执行scope.Commit进行了长时间的讨论,虽然查询不需要它,但它为应用程序层中的每个函数建立了一致的模式。顺便说一句,我们使用 NCommon 作为我们的存储库/工作单元模式,并且不必将 UoW 传递到存储库。
| 归档时间: |
|
| 查看次数: |
2274 次 |
| 最近记录: |