【发布时间】:2011-03-19 23:01:56
【问题描述】:
我正在使用 NHibernate、DI/IoC 和工作单元模式。
我见过的大多数 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(如果您尝试启动另一个 UoW,则会引发异常,就像在两个链接示例中一样),我的代码将在 this.service.WriteLog 行中崩溃在 PlaceOrder 方法中:
PlaceOrder 方法已经创建了一个活动的 UoW,WriteLog 方法将尝试打开第二个,因此 UoW 实现将因此引发异常。
那么,我该怎么办呢?
我提出了两个想法,但在我看来,这两个想法都有些“老套”。
不要在 LoggerService 中启动新的 UoW,而是假设调用代码中已经有一个活动的 UoW。
这就是我目前正在做的事情。我刚刚从 LoggerService 中删除了using (UnitOfWork.Start())的东西,并确保您不能直接调用 LoggerService,只能从其他服务中调用。
这意味着上面的代码可以工作,但是如果调用代码没有启动 UoW,LoggerService 将会崩溃,因为 LoggerService 假定已经存在。保持示例代码不变,但更改 UoW.Start() 的实现,如下所示:
a) 如果没有有效的 UoW,则开始一个新的
b) 如果已经有有一个活跃的 UoW,返回这个
这将使我能够直接和从其他服务调用 LoggerService,无论是否已经存在 UoW。
但我从未在网上的任何示例中看到过这样的事情。
(在这个例子中,只有两个服务。它可能会变得更复杂,想想一个 PlaceSpecialOrderService 类,它做了一些特殊的事情然后调用 em> PlaceOrderService.PlaceOrder()...)
有什么建议吗?
提前致谢!
编辑:
感谢您到目前为止的回答。
好吧,也许日志记录不是最好的例子。
我明白你关于使用单独的会话进行日志记录的观点,我会看看并尝试一下。
无论如何,我仍然需要找到一种方法来使嵌套服务调用起作用。
想象一下其他示例而不是日志记录,例如我上面提到的 PlaceSpecialOrderService 示例。
对于建议我在基础设施的某个地方而不是直接在服务中启动我的 UoW 的回答者:
一方面,这也是有道理的,但另一方面,这显然意味着我不能在一个服务调用中执行两个不同的事务。
我必须考虑一下,因为我很确定我会在某个地方需要这个(例如:在一个事务中保存一个订单,然后在第二个事务中做更多的事情,即使失败,订单也不会'不要回滚)。
您是否在您的应用中这样做(每次服务调用一个 UoW)?
您不需要在同一个服务调用中启动第二个 UoW 的可能性吗?
【问题讨论】:
标签: c# nhibernate architecture dependency-injection unit-of-work