Attribute 实现Aop
1、先定义一个 拦截属性 AopAttribute
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ZH.Aop { using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Activation; [AttributeUsage(AttributeTargets.Class)] public class AopAttribute : Attribute, IContextAttribute { public void GetPropertiesForNewContext(IConstructionCallMessage msg) { msg.ContextProperties.Add(new AOPProperty()); } public bool IsContextOK(Context ctx, IConstructionCallMessage msg) { AOPProperty aOPProperty = ctx.GetProperty("Aop") as AOPProperty; return aOPProperty!=null; } } }
2 实现 ContextProperty, IContributeServerContextSink
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ZH.Aop { using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; internal class AOPProperty : IContextProperty, IContributeServerContextSink { public string Name => "Aop"; public AOPProperty() { Console.WriteLine(nameof(AOPProperty)); } public void Freeze(Context newContext) { } public bool IsNewContextOK(Context newCtx) { var result = newCtx.GetProperty("Aop"); return result != null; } public IMessageSink GetServerContextSink(IMessageSink nextSink) { Aspect aspect = new Aspect(nextSink); return aspect; } } }
3、 实现事件 执行类(主要) Aspect
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Diagnostics; namespace ZH.Aop { using System.Runtime.Remoting.Messaging; using System.Dynamic; using ZH.Aop.AopListener; using ZH.Aop.ArgsModel; internal class Aspect : IMessageSink { private IMessageSink nextSink = null; public Aspect(IMessageSink messageSink) { nextSink = messageSink; } public IMessageSink NextSink => nextSink; public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) { return null; } /// <summary> /// 处理事件 /// </summary> /// <param name="msg"></param> /// <returns></returns> public IMessage SyncProcessMessage(IMessage msg) { // 方法执行之前】 dynamic defaultValue = new ExpandoObject(); var callMsg = msg as IMethodCallMessage; AopEventArgs aopEventArgs = new AopEventArgs(); aopEventArgs.StartTime = DateTime.Now; aopEventArgs.MethodName = callMsg.MethodName; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); MethodListen.GetInstance().BeginMethod(aopEventArgs); // 如果不是构造函数 if (!callMsg.MethodBase.IsConstructor) { defaultValue = ((System.Reflection.MethodInfo)(callMsg.MethodBase)).ReturnParameter.DefaultValue; // 实例 如果方法的名称是 SetName 则放弃执行 // if (callMsg.MethodName == "SetName") // return new ReturnMessage(defaultValue, callMsg.Args, callMsg.ArgCount, callMsg.LogicalCallContext, callMsg); } try { IMessage returnMsg = nextSink.SyncProcessMessage(msg); stopwatch.Stop(); aopEventArgs.OperateTime = stopwatch.ElapsedMilliseconds; aopEventArgs.EndTime = DateTime.Now; return returnMsg; } catch (Exception ex) { aopEventArgs.Exception = ex; throw; } finally { // 执行方法之后 MethodListen.GetInstance().AfterMethod(aopEventArgs); } } } }
4 另外 监听事件的执行
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ZH.Aop.AopListener { using ZH.Aop.ArgsModel; public interface IMethodListen { event EventHandler<AopEventArgs> OnMethodBegin; event EventHandler<AopEventArgs> OnMethodAfter; } }
实现上面接口:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ZH.Aop.AopListener { using ZH.Aop.ArgsModel; public class MethodListen : IMethodListen { public event EventHandler<AopEventArgs> OnMethodBegin; public event EventHandler<AopEventArgs> OnMethodAfter; private static MethodListen _methodListen = null; public static MethodListen GetInstance() { if (_methodListen == null) _methodListen = new MethodListen(); return _methodListen; } internal void BeginMethod(AopEventArgs aopEventArgs) { if (OnMethodBegin != null) { OnMethodBegin(this, aopEventArgs); } } internal void AfterMethod(AopEventArgs aopEventArgs) { if (OnMethodAfter != null) { OnMethodAfter(this, aopEventArgs); } } } }
6 参数 model
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ZH.Aop.ArgsModel { using System.Reflection; public class AopEventArgs : EventArgs { /// <summary> /// 方法名称 /// </summary> public string MethodName { get; set; } /// <summary> /// 执行时间 /// </summary> public long OperateTime { get; set; } /// <summary> /// 异常信息 /// </summary> public Exception Exception { get; set; } /// <summary> /// 开始时间 /// </summary> public DateTime StartTime { get; set; } /// <summary> /// 结束时间 /// </summary> public DateTime EndTime { get; set; } } }
测试:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ZH.Aop; using ZH.Aop.AopListener; using ZH.Aop.ArgsModel; namespace Demo.Aop { class Program { static void Main(string[] args) { MethodListen methodListen = MethodListen.GetInstance(); methodListen.OnMethodBegin += new EventHandler<AopEventArgs>(OnMethodBegin); methodListen.OnMethodAfter += new EventHandler<AopEventArgs>(OnMethodAfter); TestAop testAop = new TestAop(); for (int i=0;i<100000;i++) { var s = testAop.SetName("zheng", 3); } Console.ReadLine(); } public static void OnMethodBegin(object sender, AopEventArgs e) { Console.WriteLine($"开始执行--方法名称{e.MethodName} 开始时间:{e.EndTime}"); } public static void OnMethodAfter(object sender, AopEventArgs e) { Console.WriteLine($"执行后--方法名称{e.MethodName} 总共时间{e.OperateTime} 结束时间:{e.EndTime}"); } } [Aop] public class TestAop : ContextBoundObject { public string SetName(string name, int age) { return $"{name}{age}"; } } }