我如何分享一个'工作单元'在多个服务方法之间

本文关键字:方法 之间 单元 服务 工作 一个 何分享 分享 | 更新日期: 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之后提交