[Abp 源码分析]六、工作单元的实现 (3)

根据字面意思我们大概知道应该类似于管理 UOW 的东西,它其实只有两个作用。第一,获取当前处于激活状态的工作单元,什么叫激活状态我们后面再讲。第二个作用就是我们之前看到的,可以通过 Begin() 方法来创建一个新的工作单元。

IUnitOfWorkManager 在 Abp 框架初始化的时候就被注入了,其默认实现为 UnitOfWorkManager ,其核心方法就是 Begin() 方法。

public IUnitOfWorkCompleteHandle Begin(UnitOfWorkOptions options) { // 如果没有传入 UOW 参数,则填充一个默认的参数 options.FillDefaultsForNonProvidedOptions(_defaultOptions); // 获取当前的外部工作单元 var outerUow = _currentUnitOfWorkProvider.Current; // 如果已经存在有外部工作单元,则直接构建一个内部工作单元 if (options.Scope == TransactionScopeOption.Required && outerUow != null) { return new InnerUnitOfWorkCompleteHandle(); } // 不存在外部工作单元,则从 IOC 容器当中获取一个新的出来 var uow = _iocResolver.Resolve<IUnitOfWork>(); // 绑定外部工作单元的事件 uow.Completed += (sender, args) => { _currentUnitOfWorkProvider.Current = null; }; uow.Failed += (sender, args) => { _currentUnitOfWorkProvider.Current = null; }; uow.Disposed += (sender, args) => { _iocResolver.Release(uow); }; // 设置过滤器 if (outerUow != null) { options.FillOuterUowFiltersForNonProvidedOptions(outerUow.Filters.ToList()); } uow.Begin(options); // 绑定租户 ID if (outerUow != null) { uow.SetTenantId(outerUow.GetTenantId(), false); } // 设置当前的外部工作单元为刚刚初始化的工作单元 _currentUnitOfWorkProvider.Current = uow; return uow; }

可以看到 Begin() 方法返回的是一个类型为 IUnitOfWorkCompleteHandle 的东西,转到其定义:

/// <summary> /// Used to complete a unit of work. /// This interface can not be injected or directly used. /// Use <see cref="IUnitOfWorkManager"/> instead. /// </summary> public interface IUnitOfWorkCompleteHandle : IDisposable { /// <summary> /// Completes this unit of work. /// It saves all changes and commit transaction if exists. /// </summary> void Complete(); /// <summary> /// Completes this unit of work. /// It saves all changes and commit transaction if exists. /// </summary> Task CompleteAsync(); }

他只有两个方法,都是标识 UOW 处于已经完成的状态。

在方法上面右键查看其实现可以看到有这样一种依赖关系:

[Abp 源码分析]六、工作单元的实现

可以看到 IUnitOfWorkCompleteHandle 有两个实现,一个是 InnerUnitOfWorkCompleteHandle 还有一个则是 IUnitOfWork 接口。

首先看一下 InnerUnitOfWorkCompleteHandle:

internal class InnerUnitOfWorkCompleteHandle : IUnitOfWorkCompleteHandle { public const string DidNotCallCompleteMethodExceptionMessage = "Did not call Complete method of a unit of work."; private volatile bool _isCompleteCalled; private volatile bool _isDisposed; public void Complete() { _isCompleteCalled = true; } public Task CompleteAsync() { _isCompleteCalled = true; return Task.FromResult(0); } public void Dispose() { if (_isDisposed) { return; } _isDisposed = true; if (!_isCompleteCalled) { if (HasException()) { return; } throw new AbpException(DidNotCallCompleteMethodExceptionMessage); } } private static bool HasException() { try { return Marshal.GetExceptionCode() != 0; } catch (Exception) { return false; } } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyzds.html