我正在使用NHibernate,DI/IoC和工作单元模式。UnitOfWork(NHibernate),一次只有一个活动的UoW /会话? (需要咨询)
我见过的大多数UoW示例都要确保同时只能有一个活动的UoW /会话,例如this one和this one。
不幸的是,我不太明白,我应该如何处理两个使用UoW的服务,但是一个需要另一个。
拿这个例子:
它使用一个UOW记录程序:
public class LoggerService : ILoggerService
{
private ILoggerRepository repo;
public LoggerService(ILoggerRepository Repo)
{
this.repo = Repo;
}
public void WriteLog(string message)
{
using (UnitOfWork.Start())
{
// write log
}
}
}
...和它使用的UOW以及并调用记录器的另一个服务:
public class PlaceOrderService : IPlaceOrderService
{
private IOrderRepository repo;
private ILoggerService service;
public PlaceOrderService(IOrderRepository Repo, ILoggerService Service)
{
this.repo = Repo;
this.service = Service;
}
public int PlaceOrder(int orderNumber)
{
using (UnitOfWork.Start())
{
// do stuff
this.service.WriteLog("Order placed!"); // will throw exception!!
// do more stuff
}
}
}
如果我UoW实现确保同时只有一个活动的UoW(并且在尝试启动另一个时引发另一个异常,就像在这两个链接的示例中一样),我的代码将在PlaceOrder方法的this.service.WriteLog
行中崩溃:
已经有一个由PlaceOrder方法创建的活动UoW,并且WriteLog方法将尝试打开第二个方法,所以UoW实现会因此引发异常。
那么,我能做些什么呢?
我想出了两个想法,但都看起来“哈克”对我来说。
不要启动在LoggerService一个新的UOW,而不是假设已经有一个活跃的一个调用代码。
这就是我现在所做的。我刚刚从LoggerService中删除了using (UnitOfWork.Start())
,并确保您不能直接调用LoggerService,只能从其他服务中调用。
这意味着上面的代码可以工作,但如果调用代码没有启动UoW,LoggerService将会崩溃,因为LoggerService假定已经存在。离开示例代码,因为它是,但改变UoW.Start()这样的实现:
一)如果没有积极的UOW,开始一个新的
二)如果已经是一个活动的UoW,返回这个
这将使我可以直接调用LoggerService和其他服务,无论是否已经有一个UoW。
但是我从来没有在网上看过任何这样的例子。
(在这个例子中,只有两个服务,它可以让要复杂得多,只是觉得PlaceSpecialOrderService
类,做一些特别的东西,然后调用PlaceOrderService.PlaceOrder()
...)
任何建议?
在此先感谢!
编辑:
谢谢你到目前为止的答案。
好的,也许记录不是最好的例子。
我明白了关于使用单独的会话进行日志记录的观点,并且我会对此进行审查并尝试。
无论如何,我仍然需要找到一种方法来使嵌套服务调用工作。
想象一下其他的例子,而不是记录,就像我上面提到的PlaceSpecialOrderService例子。
向应答者暗示我什么地方开始我的UOW在基础设施,而不是直接在服务:
一方面,这是有道理的太多,但在另一方面,这显然意味着,我不能在一个服务呼叫中做两个不同的交易。
我必须考虑这一点,因为我很确定我需要这个地方(比如:在一个事务中保存订单,然后在第二个事务中做更多的事情,即使失败了,订单不会回滚)。
你是否在你的应用程序中这样做(每个服务调用一个UoW)?
难道你不需要在同一个服务调用中启动第二个UoW的可能吗?
好的,这是有道理的。但是,我仍然有同样的问题(日志记录只是一个不好的例子),请参阅上文! – 2011-03-23 22:31:49