提及AOP,其实咱们在作MVC/API 的时候应该没少接触,好比说各类的Fitter 就是典型的AOP了。html
原本在使用Polly的时候我最初的打算是使用过滤器来实现的,后来发现实现起来至关的困难,利用NetCore的中间以及过滤器去实现一个AOP的独立应用服务简直了,我有点无奈,至关的难写。api
后来又使用了,Autofac 作拦截器来实现也是有点小无力。估计仍是基础太薄弱。框架
目前我了解到的实现Polly比较方便的第三方Aop框架的有函数
(1)、AspectCore:是一款 AspNetCore轻量级的Aop解决方案。微服务
(2)、Dora.Interception 老A写的一个Aop解决方案,这个用到解决方案中就须要等到老A升级下一版了。学习
在使用Policy 的时候主要点是策略的制定,在保证代码整洁,而且不破坏当前代码逻辑的状况下,使用Aop是最合适的解决方案了。this
当咱们使用过滤器的时候咱们会发现,Pollicy 制定了一个错误规则,而且在错误过滤器中使用、抓取不到任何的错误信息,由于错误信息被错误过滤器抓取了,这个时候不会触发Pollicyspa
而后尝试着 用过滤实现一个 当程序发生错误的时候,执行另外一个方法的功能,相似Policy的重试策略或降级。3d
下面代码:日志
编写:一个过滤器类:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using System; using System.Reflection; namespace InterceptorCoreLibrary { [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method)] public class CoreExceptionFilter:Attribute, IExceptionFilter,IActionFilter { /// <summary> /// 发生错误的时候从新执行的方法 /// </summary> public string FallBackClass { get; set; } /// <summary> /// 发生错误的时候从新执行的方法 /// </summary> public string FallBackMethod { get; set; } /// <summary> /// 获取方法的参数 /// </summary> public object[] InvokeParameters { get; set; } /// <summary> /// 构造函数使用该类时参数为方法 /// </summary> /// <param name="fallBackMethod"></param> public CoreExceptionFilter(string fallBackClass, string fallBackMethod) { this.FallBackMethod = fallBackMethod; this.FallBackClass = fallBackClass; } /// <summary> /// 使用新方法 /// </summary> /// <param name="asm"></param> /// <param name="parameters"></param> /// <returns></returns> private object UseNewMethod(Assembly asm, object[] parameters) { Object obj = null; foreach (Type type in asm.GetExportedTypes()) { if (type.Name == FallBackClass) { obj = System.Activator.CreateInstance(type); foreach (var item in type.GetMethods()) { if (item.Name == FallBackMethod) { obj = type.GetMethod(FallBackMethod).Invoke(obj, parameters); } } } } return obj; } /// <summary> /// 获取全部被监控方法的参数 /// </summary> /// <param name="context"></param> public void OnActionExecuting(ActionExecutingContext context) { object[] parameters = new object[context.ActionArguments.Count]; int Count = 0; foreach (var item in context.ActionArguments) { parameters[Count] = item.Value; Count++; } InvokeParameters = parameters; } /// <summary> /// 错误的时候执行新的方法 /// </summary> /// <param name="context"></param> public void OnException(ExceptionContext context) { var objectResult = context.Exception as Exception; if (objectResult.Message != null) { //context.Result = new ObjectResult(UseNewMethod(this.GetType().Assembly, InvokeParameters)); context.Result = new ObjectResult(new { Success = true, code = 200, msg = "成功", Data = UseNewMethod(this.GetType().Assembly, InvokeParameters) }); } } public void OnActionExecuted(ActionExecutedContext context) { } } }
[CoreExceptionFilter(nameof(UserModel), nameof(Delete))] 在执行的时候我抛送一个异常信息 [CoreExceptionFilter(nameof(UserModel), nameof(Delete))] // DELETE api/values/5 [HttpDelete("{id}")] public int Delete(int id) { throw new Exception(); }
using System; using System.Collections.Generic; using System.Text; namespace InterceptorCoreLibrary { public class UserModel { public int Delete(int id) { //记录日志 //从新执行一遍代码 return id; } } }
这个时候咱们能看到过滤器先抓取了错误信息,Policy 就抓不到了,但一样实现了降级的功能。
若是咱们不使用Aop的话 直接在控制器中写
好比:这样写一个两个还行多了的话,代码就至关的乱了。
// DELETE api/values/5 [HttpDelete("{id}")] public int Delete(int id) { var PolicyExecute = Policy.Handle<Exception>().Fallback(() => { //程序报错从新执行一个新的方法 UserModel userModel = new UserModel(); userModel.Delete(id); }); //执行 PolicyExecute.Execute(() => { throw new Exception(); } ); }
以上代码虽然没有实现policy ,可是也演示出了大体使用Aop实现 Policy的过程原理。
这里贴出一份杨中科老师 在普及AspNetCore微服务课程中的代码:支持原创,
完整的代码这里贴出过:
http://www.cnblogs.com/qhbm/p/9228238.html
我在Demo中进行了简单的实现:这里就不贴出了,由于框架还不是很完善,我问了做者老A,要等到下一版出来后用在项目中才比较稳妥。你们能够关注一下老A博客。
截图说明一下两个框架的区别,到时候可根据框架须要酌情使用:
有不足之处 但愿你们指出相互学习,
本文原创:转载请注明出处 谢谢!