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;
        }
        /// 
        /// 处理事件
        /// 
        /// 
        /// 
        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 OnMethodBegin;
        event EventHandler 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 OnMethodBegin;
        public event EventHandler 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
    {
        /// 
        /// 方法名称
        /// 
        public string MethodName { get; set; }

        /// 
        /// 执行时间
        /// 
        public long OperateTime { get; set; }

        /// 
        /// 异常信息
        /// 
        public  Exception Exception { get; set; }
        /// 
        /// 开始时间
        /// 
        public DateTime StartTime { get; set; }
        /// 
        /// 结束时间
        /// 
        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(OnMethodBegin);
            methodListen.OnMethodAfter += new EventHandler(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}";
        }

    }

}

 

转载于:https://www.cnblogs.com/hnzheng/p/9173234.html

你可能感兴趣的:(Attribute 实现Aop)