我如何分享一个'工作单元'在多个服务方法之间
本文关键字:方法 之间 单元 服务 工作 一个 何分享 分享 | 更新日期: 2023-09-27 18:04:17
我在应用程序服务中实现工作单元模式时遇到了一个问题,我正在构建该服务作为原型的一部分。我想我不是:
a)在autoface功能中缺少一些我不知道的东西它可以执行或
b)完全误用了工作单元模式,需要重构我的服务和/或存储库。
本质上,我的问题源于我的服务中的代码共享。具体来说,我有一个名为CreateCustomerAsync(…)
的服务方法,并在其中构建了一个工作单元(包装一个db连接并开始一个db事务),并使用存储库将数据插入到几个数据库表中。直到我想从该方法(并且在UOW的范围内)调用到另一个名为AddCustomerToGroupAsync(…)
的服务方法,以便(在同一UOW中)将客户添加到组(向链接表添加一行),这种方法才正常工作。AddCustomerToGroupAsync
本身在内部使用自己的工作单元,以确保其存储库操作也在DB事务中发生。
目前,我不能在相同的UOW内完成所有这些操作-事实上,这样的代码实际上根本不起作用,因为最内部的UOW正在运行在不同的连接上,它无法看到已插入到外部事务中的客户!我可以重新排序代码,以便AddCustomerToGroupAsync
调用在父UOW之外,但随后我失去了数据库完整性。
所以-我大致(这不是语法正确-但代表我所面临的问题)像这样:
public async Task<int> CreateCustomerAsync(string name, int groupid)
{
// do some validation etc..
// NOTE: UnitOfWork and CustomerRepository are scoped to InstancePerMatchingLifetimeScope for 'tx'
using(var scope = this.Container.BeginLifetimeScope("tx"))
using(var uow = scope.Resolve<UnitOfWork>())
{
// NOTE: ResolveRepository is an extension method - the repo is having the uow injected into it
var customerrepository = uow.ResolveRepository<CustomerRepository>();
// multiple repository calls all within the same UOW/db transaction
int newid = await customerrepository.CreateAsync(name);
await customerrepository.ActivateAsync(newid);
// here we invoke our seperate service method... and which I would *like* to execute within
// this same UOW - so if it fails then all of the db statements executed so far get rolled back
await this.AddCustomerToGroupAsync(newid, groupid);
uow.Commit();
}
}
public async Task<bool> AddCustomerToGroupAsync(int customerId, int groupId)
{
// really here I'd LIKE to resolve the same lifetime scope that was constructed in the parent if it doesnt
// exist with the tag specified already...
// if i could do that then I would be able to resolve the *same* unit of work which would be a step forward
using(var scope = this.Container.BeginLifetimeScope("tx"))
using (var uow = scope.Resolve<UnitOfWork>())
{
var grouprepository = uow.ResolveRepository<GroupRepository>();
// two repository calls that need to be wrapped in the same UOW/TX
int linkid = await grouprepository.CreateLinkAsync(customerId, groupId);
await grouprepository.ActivateAsync(linkid);
uow.Commit();
}
}
任何指针尝试实现这一点,还是我的方法从根本上被误导了?
欢呼。
考虑为AddCustomerToGroupAsync编写一个私有方法来完成大部分工作。
private async Task<bool> AddCustomerToGroupInternalAsync(int customerId, int groupId, UnitOfWork uow)
{ ../* All the code in the AddCustomerToGroupAsync inside the unitOfWork */. }
对于现有的AddCustomerToGroupAsync方法,您可以打开一个作用域,解析unitOfWork并将其传递给AddCustomerToGroupInternalAsync方法。类似地,对于现有的CreateCustomerAsync方法,您可以将在该方法中解析的UnitOfWork传递给AddCustomerToGroupInternalAsync方法。
你现在可以打电话了。在调用AddCustomerToGroupInternalAsync之后提交