【发布时间】:2015-12-29 04:25:48
【问题描述】:
您好,我正在使用 Unity 来管理我的服务层,而后者又与管理所有存储库的 UnitOfWork 对话。
我的一些服务调用其他服务,我的问题是如何在服务层之间传递相同的 UnitOfWork?
在我的情况下,所有控制器操作都是从 GUI 对计时器上的每个按钮操作或事件启动的,这就是为什么我有一个工厂来按需创建 UnitOfWork,但这会导致问题,因为我不知道如何通过这个服务之间的 UnitOfWork。
特别困难的是知道如何将这个特定的 UnitOfWork 实例注入到服务构造函数中。请注意,某些服务可能运行时间很长(后台线程运行 10 分钟左右),我不知道这是否对设计有任何影响。
当前,从其他服务调用的服务正在创建自己的 UnitOfWork,这会导致事务设计和实体框架实体跟踪出现问题。
欢迎提出建议!
class OtherService : IOtherService
{
public OtherService(IUnitOfWorkFactory unitOfworkFactory,
ISettingsService settingsService)
{
UnitOfWorkFactory = unitOfworkFactory;
SettingsService = settingsService;
}
IUnitOfWorkFactory UnitOfWorkFactory;
ISettingsService SettingsService;
function SomeSeviceCall()
{
// Perhaps one way is to use a factory to instantiate a
// SettingService, and pass in the UnitOfWork here?
// Ideally it would be nice for Unity to handle all of
// the details regardless of a service being called from
// another service or called directly from a controller
// ISettingsService settingsService =
// UnityContainer.Resolve<ISettingService>();
using (var uow = UnitOfWorkFactory.CreateUnitOfWork())
{
var companies = uow.CompaniesRepository.GetAll();
foreach(Company company in companies)
{
settingsService.SaveSettings(company, "value");
company.Processed = DateTime.UtcNow();
}
uow.Save();
}
}
}
class SettingsService : ISettingsService
{
public SettingsService(IUnitOfWorkFactory unitOfworkFactory)
{
UnitOfWorkFactory = unitOfworkFactory;
}
IUnitOfWorkFactory UnitOfWorkFactory;
// ISettingsService.SaveSettings code in another module...
function void ISettingsService.SaveSettings(Company company,
string value)
{
// this is causing an issue as it essentially creates a
// sub-transaction with the new UnitOfWork creating a new
// Entiy Framework context
using (var uow = UnitOfWorkFactory.CreateUnitOfWork())
{
Setting setting = new Setting();
setting.CompanyID = company.CompanyID;
setting.SettingValue = value;
uow.Insert(setting);
uow.Save();
}
}
}
【问题讨论】:
-
看this question。我认为selected answer 也可以解决您的问题。
-
@Steven 谢谢,我喜欢命令/处理程序设计的想法,如何通过命令装饰器在多个服务之间共享上下文?如果您有任何调用装饰器并返回数据的代码示例,那将具有巨大的价值。
-
我错过了您使用 Unity 的事实。使用 Unity 注册通用装饰器是非常困难的(尽管您可以让它与 Unity 的拦截支持一起工作)。然而,理论上这只是定义一个装饰器(比如
TransactionCommandHandlerDecorator)的问题,它在调用decorated.Handle(command)之后注入一个工作单元并在Handle方法中调用uwo.Save。您注册此装饰器以包裹在您的命令处理程序周围,并使用“每个网络请求”的生活方式注册工作单元。 -
@Steven 谢谢,我不必使用 Unity,任何其他 DI 容器都可以,如果您知道用于实现上述目的的容器,我也可以使用它,因为我仍在安装up 概念样板代码
标签: c# .net entity-framework dependency-injection unity-container