• 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,到此工作单元工作的大体流程就讲完了,其中还有很多细节需要仔细的研究源码才能了解,

    待编辑...

  • 相关阅读:
    Kubernetes 运维小记:node 为系统保留最低资源
    见异思迁:K8s 部署 Nginx Ingress Controller 之 kubernetes/ingressnginx
    Kubernetes 部署 Nginx Ingress Controller 之 nginxinc/kubernetesingress
    Kubernetes 与 Helm:使用同一个 Chart 部署多个应用
    终于成功部署 Kubernetes HPA 基于 QPS 进行自动伸缩
    排查 Kubernetes HPA 通过 Prometheus 获取不到 http_requests 指标的问题
    搭建 Kubernetes 高可用集群
    排查 k8s 集群 master 节点无法正常工作的问题
    Kubernetes 升级记录:从 1.16.3 升级至 1.17.0
    ASP.NET Core 获取主机名时的 "Decoded string is not a valid IDN name" 错误
  • 原文地址:https://www.cnblogs.com/dongshuangjie/p/5305414.html
走看看 - 开发者的网上家园