<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      aspnetcore中aop的實現

      aaspnetcore開發框架中實現aop不僅僅在業務上,在代碼的優雅簡潔和架構的穩定上都有著至關重要。

      下面介紹三種用過的。

       

      第一種通過System.Reflection的DispatchProxy類來實現

      首先新建一個aspnetcore項目

       

      針對業務代碼WarService加了一個代理的方法

      public interface IWarService
          {
              string WipeOut();
              IWarService Proxy(IWarService warService);
          }
      
      
       public class WarService : IWarService
          {
              public IWarService Proxy(IWarService warService)
              {
                  return WarDispatch<IWarService>.Create(warService);
              }
      
              public string WipeOut()
              {
                  return "us is over";
              }
          }

      具體的WarDispatch就是核心代碼了,繼承自DispatchProxy。這里的before和after的實現就是針對實現了代碼的service提前挖坑。

      public class WarDispatch<T> : DispatchProxy where T : class
          {
              private T Target { get; set; }
              public static T Create<T>(T target) where T : class
              {
                  var proxy = Create<T, WarDispatch<T>>() as WarDispatch<T>;
                  proxy.Target = target;
                  return proxy as T;
              }
      
              protected override object? Invoke(MethodInfo? targetMethod, object?[]? args)
              {
                  Before().Wait();
                  var result = targetMethod.Invoke(Target, args);
                  After().Wait();
                  return result;
              }
      
              Task Before()
              {
                  return Task.CompletedTask;
              }
      
              Task After()
              {
                  return Task.CompletedTask;
              }
          }

      實現代碼也相當簡單

      [ApiController]
          [Route("[controller]")]
          public class RescueEarthController : ControllerBase
          {
              private IWarService _warService;
              
              public RescueEarthController(IWarService warService)
              {
                  _warService = warService;
              }
      
              [HttpGet(Name = "AnnihilateHegemony")]
              public string AnnihilateHegemony()
              {
                  var proxy = _warService.Proxy(_warService); //代理
                  return proxy.WipeOut();
              }
      
              [HttpGet("two")]
              public string AnnihilateHegemonyTwo()
              {
                  return _warService.WipeOut();
              }
          }

      當然不要忘了注入下服務類

      builder.Services.AddScoped<IWarService, WarService>();

      上面的方式是我自己想出來的,具體到項目中需要改進的地方應該還有很多,但是足夠簡單,功能也比較單一。

       

      下面簡單介紹下AspectCore.DynamicProxy現成組件的代理使用。

      首先引用aspnetcore.extensions.dependencyinjection包

      在program中使用動態代碼

       builder.Host.UseServiceProviderFactory(new DynamicProxyServiceProviderFactory());
                  builder.Services.ConfigureDynamicProxy(o =>{ 
                  //添加aop的配置
                  //該項目用attribute所以無需配置
                 
                  });

      內存的緩存代理

       public class CacheDeleteInterceptorAttribute:AbstractInterceptorAttribute
          {
              private readonly Type[] _types;
              private readonly string[] _methods;
              public CacheDeleteInterceptorAttribute(Type[] types, string[] methods)
              {
                  if (types.Length != methods.Length)
                  {
                      throw new Exception("Types必須跟Methods數量一致");
                  }
                  _types = types;
                  _methods = methods;
              }
      
              public override async Task Invoke(AspectContext context, AspectDelegate next)
              {
                  var cache = context.ServiceProvider.GetService<MemoryCache>();
                  await next(context);
                  for (int i = 0; i < _types.Length; i++)
                  {
                      var type = _types[i];
                      var method = _methods[i];
                      string key = "Methods:" + type.FullName + "." + method;
                      cache.Remove(key);
                  }
              }
          }
       public class CacheInterceptorAttribute : AbstractInterceptorAttribute
          {
              public override async Task Invoke(AspectContext context, AspectDelegate next)
              {
                  bool isAsync = context.IsAsync();
                  var methodReturnType = context.GetReturnParameter().Type;
                  if(methodReturnType==typeof(void)|| methodReturnType==typeof(Task) || methodReturnType == typeof(ValueTask))
                  {
                      await next(context);
                      return;
                  }
                  var returnType = methodReturnType;
                  if (isAsync)
                  {
                      returnType = returnType.GenericTypeArguments.FirstOrDefault();
                  }
                  //string param = GetParaName(context.Parameters); //獲取方法的參數名,
                  string key = $"Methods:{context.ImplementationMethod.DeclaringType.FullName}.{context.ImplementationMethod.Name}";//獲取方法名稱,也就是緩存key值
                  var cache = context.ServiceProvider.GetService<MemoryCache>(); //可以使用自定義的redis或者其他緩存
                  if (cache.Get(key) != null)
                  {
                      //反射獲取緩存值
                      var value = typeof(MemoryCache).GetMethod("MemoryCache.Get").MakeGenericMethod(returnType).Invoke(cache, new[] {
                          key
                          //, param 
                      });
                      if (isAsync)
                      {
      
                          //判斷是Task還是ValueTask
                          if (methodReturnType == typeof(Task<>).MakeGenericType(returnType))
                          {
                              //反射獲取Task<>類型的返回值,相當于Task.FromResult(value)
                              context.ReturnValue = typeof(Task).GetMethod(nameof(Task.FromResult)).MakeGenericMethod(returnType).Invoke(null, new[] { value });
                          }
                          else if (methodReturnType == typeof(ValueTask<>).MakeGenericType(returnType))
                          {
                              //反射構建ValueTask<>類型的返回值,相當于new ValueTask(value)
                              context.ReturnValue = Activator.CreateInstance(typeof(ValueTask<>).MakeGenericType(returnType), value);
                          }
                      }
                      else
                      {
                          context.ReturnValue = value;
                      }
                      return;
                  }
                  await next(context);
                  object returnValue;
                  if (isAsync)
                  {
                      returnValue = await context.UnwrapAsyncReturnValue();
                      //反射獲取異步結果的值,相當于(context.ReturnValue as Task<>).Result
                      //returnValue = typeof(Task<>).MakeGenericType(returnType).GetProperty(nameof(Task<object>.Result)).GetValue(context.ReturnValue);
      
                  }
                  else
                  {
                      returnValue = context.ReturnValue;
                  }
                  cache.Set(key
                      //, param
                      , returnValue);
                  if(ExpireSeconds > 0)
                  {
                      cache.Set(key, TimeSpan.FromSeconds(ExpireSeconds));//設置key的過期時間
                  }
              }
      
              //private string GetParaName(object[] parameters)
              //{
              //    throw new NotImplementedException();
              //}
      
              /// <summary>
              /// 緩存秒數
              /// </summary>
              public int ExpireSeconds { get; set; }
          }

      dbcontext的代理

      public class TransactionInterceptorAttribute : AbstractInterceptorAttribute
          {
              //public override async Task Invoke(AspectContext context, AspectDelegate next)
              //{
              //    var dbcontext = context.ServiceProvider.GetService<CommonDbContext>();
              //    if (dbcontext.Database.CurrentTransaction != null)
              //    {
              //        await dbcontext.Database.BeginTransactionAsync();
              //        try
              //        {
              //            await next(context);
              //            await dbcontext.Database.CommitTransactionAsync();
              //        }catch(Exception ex)
              //        {
              //           await dbcontext.Database.RollbackTransactionAsync();
              //            throw ex;
              //        }
              //    }
              //    else
              //    {
              //        await next(context);
              //    }
              //}//一個context
      
              public override async Task Invoke(AspectContext context, AspectDelegate next)
              {
                  var dbcontext = context.ServiceProvider.GetService<CommonDbContext>();
                  var dbcontextNext = context.ServiceProvider.GetService<NextDbContext>();
                  var transactionManager = dbcontext.Database.GetService<IDbContextTransactionManager>();
                  var transaction = await transactionManager.BeginTransactionAsync();
      
                  if (transaction != null)
                  {
                      await dbcontext.Database.BeginTransactionAsync();
                      try
                      {
                          await next(context);
                          await transaction.CommitAsync();
                      }
                      catch (Exception ex)
                      {
                          await transaction.RollbackAsync();
                          throw ex;
                      }
                  }
                  else
                  {
                      await next(context);
                  }
              }//多個context
          }
       public class CommonDbContext:DbContext
          {
              public CommonDbContext(DbContextOptions<CommonDbContext> options):base(options)
              {
      
              }
          }
      
          public class NextDbContext : DbContext
          {
              public NextDbContext(DbContextOptions<CommonDbContext> options) : base(options)
              {
      
              }
          }

      使用就是這么簡單

       public class TestOperatorDbBusiness
          {
              [TransactionInterceptor]
              public async ValueTask Add()
              {
                  //TODO事務操作
              }
          }

       

      上面的代理組件功能非常多,項目中需要自己去研究更多更全的用法。

      上面代碼的demo

      exercisebook/AOP at main · liuzhixin405/exercisebook (github.com)

      還有Castle.DynamicProxy,這個比較復雜一點。具體用法給個實例demo

      exercisebook/AspNetCoreAOP at main · liuzhixin405/exercisebook (github.com)

      總結:

      一個aspnetcore中需要用到aop的地方非常多,框架自帶的中間件,filter過濾器,efcore自帶Interceptor都可以拿來用。

      中間件例如mediator,這里面的攔截器也非常多,還有好多等待發掘。

      當然自己也可以定義一些簡單的中間層來做攔截。

      相信多了解 在框架中有需要用的地方會事半功倍。

      最后附上自己寫的超級簡單的aop組件,沒有引用任何第三方組件,當然功能方面有待豐富,有興趣的伙伴可以幫忙改進改善。

      liuzhixin405/AspNetCoreSimpleAop (github.com)

       

      posted @ 2023-03-23 23:37  星仔007  閱讀(571)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 国产精品一区二区三区自拍| 日本高清在线播放一区二区三区 | 国产免费福利网站| 来安县| 国产国产人免费人成免费| 亚洲av日韩av综合在线观看| 国产人妻精品无码av在线| 国产最大的福利精品自拍| 99久久亚洲综合精品成人网| 少妇一边呻吟一边说使劲视频| 内射中出无码护士在线| 在线看国产精品三级在线| 国产乱人伦av在线无码| 中文字幕久久波多野结衣av| 最新偷拍一区二区三区| 久久精品亚洲中文无东京热| 国产高清小视频一区二区| 中文字幕国产日韩精品| 正在播放国产真实哭都没用| 综合成人亚洲网友偷自拍| 人妻av无码系列一区二区三区| 无码中文字幕乱码一区| 日韩一本不卡一区二区三区| 精品日韩人妻中文字幕| 日韩av影院在线观看| 国产精品不卡一区二区三区| 成年女人片免费视频播放A| 久久午夜无码免费| 亚洲日韩亚洲另类激情文学| 亚洲成av人片乱码色午夜| 日本一道一区二区视频| 国产一区二区亚洲精品| 国产精品久久久久久无毒不卡| 二区三区亚洲精品国产| 国产精品制服丝袜第一页| 亚洲色欲色欲天天天www| 在线观看亚洲欧美日本| 亚洲国产青草衣衣一二三区 | av区无码字幕中文色| 亚洲成av人片天堂网无码| 欧美视频专区一二在线观看 |