ASP.NET Boilerplate 工作单元

从上往下说起,框架使用castle拦截器,拦截实现了IApplication、IRepository接口的所有方法,和使用了UnitOfWork 特性的方法,代码如下

internal class UnitOfWorkInterceptor : IInterceptor  
{
    private readonly IUnitOfWorkManager _unitOfWorkManager;

    public UnitOfWorkInterceptor(IUnitOfWorkManager unitOfWorkManager)
    {
        _unitOfWorkManager = unitOfWorkManager;
    }

    public void Intercept(IInvocation invocation)
    {
        if (_unitOfWorkManager.Current != null)
        {
            //Continue with current uow
            invocation.Proceed();
            return;
        }

        var unitOfWorkAttr = UnitOfWorkAttribute.GetUnitOfWorkAttributeOrNull(invocation.MethodInvocationTarget);
        if (unitOfWorkAttr == null || unitOfWorkAttr.IsDisabled)
        {
            //No need to a uow
            invocation.Proceed();
            return;
        }

        //No current uow, run a new one
        PerformUow(invocation, unitOfWorkAttr.CreateOptions());
    }
....

我们会看到如果当前工作单元为null的情况下会执行 PerformUow,那让我们看看它又做了哪些工作呢,看代码

  private void PerformSyncUow(IInvocation invocation, UnitOfWorkOptions options)
  {
      using (var uow = _unitOfWorkManager.Begin(options))
      {
          invocation.Proceed();
          uow.Complete();
      }
  }

拦截器注入了UnitOfWorkManager,那就看它,UnitOfWorkManager有一个Current属性和三个重载的Begin方法,UnitOfWorkManager调用Begin方法,方法通过IOC解析得到一个uow实例,然后做了两个工作,一是给当前Current赋值,二是调用uow的begin方法,代码如下

 public IUnitOfWorkCompleteHandle Begin(UnitOfWorkOptions options)
 {
     options.FillDefaultsForNonProvidedOptions(_defaultOptions);

     if (options.Scope == TransactionScopeOption.Required && _currentUnitOfWorkProvider.Current != null)
     {
         return new InnerUnitOfWorkCompleteHandle();
     }

     var uow = _iocResolver.Resolve<IUnitOfWork>();

     ...

     uow.Begin(options);

     _currentUnitOfWorkProvider.Current = uow;

     return uow;
 }

那就让我看看uow的begin方法究竟做了哪些工作,在UnitOfWorkBase类里面看,UnitOfWorkBase实现了IUnitOfWork接口,主要关心的就是Begin、Complete、SaveChanges三个方法的实现,那就让我们看看UnitOfWorkBase代码

public abstract class UnitOfWorkBase : IUnitOfWork
{
    public string Id { get; private set; }

    public IUnitOfWork Outer { get; set; }

    public UnitOfWorkOptions Options { get; private set; }

    ...

    protected UnitOfWorkBase(IUnitOfWorkDefaultOptions defaultOptions)
    {
        Id = Guid.NewGuid().ToString("N");
        _filters = defaultOptions.Filters.ToList();
        AbpSession = NullAbpSession.Instance;
    }

    /// <inheritdoc/>
    public void Begin(UnitOfWorkOptions options)
    {
        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        PreventMultipleBegin();
        Options = options; //TODO: Do not set options like that!

        SetFilters(options.FilterOverrides);
        //实现在EfUnitOfWork里
        BeginUow();
    }

    /// <inheritdoc/>
    public abstract void SaveChanges();

 public void Complete()
 {
     PreventMultipleComplete();
     try
     {
         CompleteUow();
         _succeed = true;
         OnCompleted();
     }
     catch (Exception ex)
     {
         _exception = ex;
         throw;
     }
 }

 protected abstract void BeginUow();

 protected abstract void CompleteUow();

 ...

我们看到Begin、Complete方法分别调用了BeginUow、CompleteUow方法,真正干活的就是这个方法了,这两个方法的实现在具体的UnitOfWork类里,如EfUnitOfWork,到此工作单元工作的大体流程就讲完了,其中还有很多细节需要仔细的研究源码才能了解,

待编辑...

原文地址:https://www.cnblogs.com/dongshuangjie/p/5305414.html