您好我正在使用Unity来管理我的服务层,这反过来又与管理所有存储库的UnitOfWork对话。UnitOfWork with Unity and Entity Framework
我的一些服务调用其他服务,我的问题是如何在服务层之间传递相同的UnitOfWork?
在我的情况下,所有的控制器操作都是从每个按钮动作或事件启动一个定时器,这就是为什么我有一个工厂按需创建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();
}
}
}
看看[这个问题](http://stackoverflow.com/questions/10585478/one-dbcontext-per-web-request-why)。我认为[选定的答案](http://stackoverflow.com/a/10588594/264697)也解决您的问题。 – Steven
@Steven谢谢,我喜欢命令/处理程序设计的想法,如何通过命令装饰器跨多个服务共享上下文?如果你有被调用的装饰器的任何代码示例和返回的数据具有巨大的价值。 – g18c
我错过了使用Unity的事实。对于Unity来说,注册通用装饰器是非常困难的(尽管你可能会使它与Unity的拦截支持一起工作)。然而,从理论上讲,它只是定义一个装饰器(比如'TransactionCommandHandlerDecorator'),它在获得一个工作单元后,在调用'decorated.Handle(command)之后,在'Handle'方法中调用'uwo.Save'。 '。您注册这个装饰器以包裹您的命令处理程序,并以“每个Web请求”生活方式注册工作单元。 – Steven