服务器之家

服务器之家 > 正文

聊一下Castle DynamicProxy基本用法(AOP)

时间:2021-06-30 02:13     来源/作者:UP技术控

聊一下Castle DynamicProxy基本用法(AOP)

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点……是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

动态代理是实现AOP的一种方式,即在开发过程中我们不需要处理切面中(日志等)的工作,而是在运行时,通过动态代理来自动完成。Castle DynamicProxy是一个实现动态代理的框架,被很多优秀的项目用来实现AOP编程,EF Core、Autofac等。

为业务类添加AOP拦截器

 

  1. /// <summary> 
  2.   /// 为业务类添加AOP拦截器。 
  3.   /// </summary> 
  4.   public class InterceptorAttribute:PlutoStudio.Aop.InterceptorAttribute 
  5.   { 
  6.       /// <summary> 
  7.       /// 拦截方法的执行,如果当前方法有拦截处理器,则执行处理器。 
  8.       /// </summary> 
  9.       /// <param name="invocation">被拦截的调用目标对象</param> 
  10.       public override void Intercept(IInvocation invocation) 
  11.       { 
  12.           var method = invocation.Method; 
  13.           var processors = method.GetCustomAttributes(typeof(IInterceptorProcessor),true).Cast<IInterceptorProcessor>().ToList(); 
  14.           processors.ForEach(p => PlutoStudio.MefContainer.Container.ComposeParts(p)); 
  15.           if (processors.Count>0) 
  16.           { 
  17.               processors.ForEach(p => p.PreProcess(invocation)); 
  18.               try 
  19.               { 
  20.                   invocation.Proceed(); 
  21.                   processors.ForEach(p => p.PostProcess(invocation, null)); 
  22.               } 
  23.               catch (Exception ex) 
  24.               { 
  25.                   processors.ForEach(p => p.PostProcess(invocation, ex)); 
  26.                   throw; 
  27.               } 
  28.           } 
  29.           else 
  30.           { 
  31.               invocation.Proceed(); 
  32.           } 
  33.       } 
  34.   } 
  1. /// <summary> 
  2.  /// 拦截器处理器接口。 
  3.  /// </summary> 
  4.  public interface IInterceptorProcessor 
  5.  { 
  6.      /// <summary> 
  7.      /// 拦截器处理方法,在目标方法执行前执行。 
  8.      /// </summary> 
  9.      /// <param name="invocation">拦截的目标对象</param> 
  10.      void PreProcess(IInvocation invocation); 
  11.  
  12.      /// <summary> 
  13.      /// 拦截器处理方法,在目标方法执行后执行。 
  14.      /// </summary> 
  15.      /// <param name="invocation">拦截的目标对象</param> 
  16.      /// <param name="ex">目标方法的异常</param> 
  17.      void PostProcess(IInvocation invocation,Exception ex); 
  18.  } 

日志处理器

 

可以将目标方法的信息保存到日志系统中

  1. /// <summary> 
  2.   /// 日志处理器,可以将目标方法的信息保存到日志系统中。 
  3.   /// </summary> 
  4.   [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
  5.   public class LogAttribute : Attribute, IInterceptorProcessor 
  6.   { 
  7.       [Import(AllowDefault = true)] 
  8.       public ILog Log { get; set; } 
  9.  
  10.       /// <summary> 
  11.       /// 在目标方法执行完成后执行,这里会记录目标方法的相关信息并写入日志系统。 
  12.       /// </summary> 
  13.       /// <param name="invocation"></param> 
  14.       /// <param name="ex"></param> 
  15.       public void PostProcess(IInvocation invocation, Exception ex) 
  16.       { 
  17.           if (Log != null
  18.           { 
  19.               var @class = invocation.TargetType.FullName; 
  20.               var method = invocation.Method.Name
  21.               var parameterNames = invocation.Method.GetParameters().Select(p => p.Name).ToList(); 
  22.               var args = invocation.Arguments; 
  23.               var parameters = new Dictionary<string, object>(); 
  24.               for (int i = 0; i < parameterNames.Count; i++) 
  25.               { 
  26.                   parameters.Add(parameterNames[i], args[i]); 
  27.               } 
  28.               var returnValue = invocation.ReturnValue; 
  29.               var stackTrace = new StackTrace(true); 
  30.               var stacks = stackTrace.GetFrames(); 
  31.               var stack = stacks.SkipWhile(i => i.GetMethod().Name != invocation.Method.Name).Select(GetStack); 
  32.               var log = new TraceLog 
  33.               { 
  34.                   Class = @class, 
  35.                   Method = method, 
  36.                   Parameter = parameters, 
  37.                   ReturnValue = returnValue, 
  38.                   Strack = stack, 
  39.                   Exception = ex, 
  40.               }; 
  41.               Log.Custom(log); 
  42.  
  43.           } 
  44.       } 
  45.  
  46.       private object GetStack(StackFrame frame) 
  47.       { 
  48.           var method = frame.GetMethod(); 
  49.           var type = method.ReflectedType; 
  50.           if (type.FullName.StartsWith("Castle.Proxies")) 
  51.           { 
  52.               type = type.BaseType; 
  53.           } 
  54.           return new 
  55.           { 
  56.               Method = method.Name
  57.               Type = type.FullName, 
  58.               File = frame.GetFileName(), 
  59.               Line = frame.GetFileLineNumber(), 
  60.           }; 
  61.       } 
  62.  
  63.       public void PreProcess(IInvocation invocation) 
  64.       { 
  65.       } 
  66.   } 
  1. /// <summary> 
  2.   /// 系统跟踪日志,由<see cref="LogAttribute"/>生成。 
  3.   /// </summary> 
  4.   public class TraceLog 
  5.   { 
  6.       /// <summary> 
  7.       /// 当前日志记录的目标类。 
  8.       /// </summary> 
  9.       public string Class { get; internal set; } 
  10.       /// <summary> 
  11.       /// 当前日志跟踪到的异常。 
  12.       /// </summary> 
  13.       public Exception Exception { get; internal set; } 
  14.       /// <summary> 
  15.       /// 当前日志记录的目标方法。 
  16.       /// </summary> 
  17.       public string Method { get; internal set; } 
  18.       /// <summary> 
  19.       /// 当前日志记录的目标方法的参数。 
  20.       /// </summary> 
  21.       public Dictionary<string, object> Parameter { get; internal set; } 
  22.       /// <summary> 
  23.       /// 当前日志记录的目标方法的返回值。 
  24.       /// </summary> 
  25.       public object ReturnValue { get; internal set; } 
  26.  
  27.       /// <summary> 
  28.       /// 当前日志记录的目标方法的调用栈。 
  29.       /// </summary> 
  30.       public IEnumerable<object> Strack { get; internal set; } 
  31.   } 

原文链接:https://mp.weixin.qq.com/s/CgnC5D4qeBKSsrqzMV4p-w

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021德云社封箱演出完整版 2021年德云社封箱演出在线看
2021德云社封箱演出完整版 2021年德云社封箱演出在线看 2021-03-15
返回顶部