我正在使用 NHibernate、DI/IoC 和工作单元模式。
我见过的大多数 UoW 示例都确保同时只能有一个事件的 UoW/ session ,例如 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 实现将因此抛出异常。
那么,我能做些什么呢?
我想出了两个想法,但对我来说这两个想法都有些“hacky”。
这就是我目前正在做的事情。我刚刚从 LoggerService 中删除了
using (UnitOfWork.Start())
内容,并确保您不能直接调用 LoggerService,只能从其他服务调用。这意味着上面的代码可以工作,但如果调用代码没有启动 UoW,LoggerService 将崩溃,因为 LoggerService 假定一个已经存在。
a) 如果没有事件的 UoW,则开始一个新的 UoW
b) 如果已经有 是 一个事件的 UoW,则返回这个
这将使我能够直接从其他服务调用 LoggerService,无论是否已经存在 UoW。
但我从来没有在网上的任何例子中看到过这样的事情。
(在这个例子中,只有两个服务。它可能会变得更复杂,想想一个
PlaceSpecialOrderService
类,它会做一些特殊的事情,然后调用 PlaceOrderService.PlaceOrder()
...)有什么建议吗?
提前致谢!
编辑:
感谢您到目前为止的答案。
好吧,也许日志记录不是最好的例子。
我明白您关于使用单独 session 进行日志记录的观点,我会看看并尝试一下。
无论如何,我仍然需要找到一种方法来使嵌套的服务调用工作。
想象一些其他示例而不是日志记录,例如我上面提到的 PlaceSpecialOrderService 示例。
对于建议我在基础设施中的某个地方而不是直接在服务中开始我的 UoW 的回答者:
一方面,这也有道理,但另一方面,这显然意味着我不能在一次服务调用中执行两个不同的事务。
我必须考虑一下,因为我很确定我会在某个地方需要它(例如:在一个交易中保存一个订单,然后在第二个交易中做更多的事情,即使失败了,订单也不会不会被回滚)。
您是否在您的应用程序中采用这种方式(每个服务调用一个 UoW)?
您是否曾经需要在同一个服务调用中启动第二个 UoW 的可能性?
最佳答案
我认为您已经发现了一个非常特殊的场景,当您永远不应该将同一个 Session 用于业务服务和日志服务。 UnitOfWork 是“业务事务”,但日志显然不是事务的一部分。如果您的业务逻辑抛出异常,它将回滚您的日志!!!使用单独的 session 进行日志记录(使用单独的连接字符串限制在当前事务中登记)。
关于c# - UnitOfWork (NHibernate),一次只有一个事件的 UoW/ session ? (需要咨询),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5365506/