AOP 学习

AOP学习

一直以来对AOP的了解都是限制在理论层面,没有从实现的角度去做。在网上也看了许多列子,最后借鉴结合现有情况揉合所用


核心源码

方法属性部分
   /// <summary>
    /// 日志特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Method,AllowMultiple =true,Inherited =true)]
    public class LogAttribute:Attribute
    {
        public string FunctionCode { get; set; }

        public ExecuteTime Sort { get; set; }

        public int Order { get; set; }
    }

    /// <summary>
    /// 权限特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
    public class PermissionsAttribute : Attribute
    {
        public string FunctionCode { get; set; }

        public ExecuteTime Sort { get; set; }

        public int Order { get; set; }
    }

    /// <summary>
    /// 性能统计特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
    public class PerformanceAttribute : Attribute
    {
        public ExecuteTime Sort { get; set; }

        public int Order { get; set; }
    }

    public enum ExecuteTime
    {
        BeforeRun,
        AfterRun
    }

public class AttributeInfo
    {
        public int Order { get; set; }

        public ExecuteTime Time { get; set; }

        public string AttributeName { get; set; }

        public IList<System.Reflection.CustomAttributeNamedArgument> Datas { get; set; }
    }

Remote代理部分
/// <summary>
    /// 类 属性
    /// </summary>
    [AttributeUsage(AttributeTargets.Class,AllowMultiple =true,Inherited =true)]
    public class AspectAttribute : ProxyAttribute
    {
        public override MarshalByRefObject CreateInstance(Type targetType)
        {
            AspectProxy realProxy = new AspectProxy(targetType);
            return realProxy.GetTransparentProxy() as MarshalByRefObject;
        }
    }

public class AspectProxy : RealProxy
    {
        public AspectProxy(Type targetType)
            : base(targetType) { }


        public override IMessage Invoke(IMessage msg)
        {
            if (msg is IConstructionCallMessage)
            {
                IConstructionCallMessage constructCallMsg = msg as IConstructionCallMessage;
                IConstructionReturnMessage constructionReturnMessage = InitializeServerObject((IConstructionCallMessage)msg);
                RealProxy.SetStubData(this, constructionReturnMessage.ReturnValue);
                return constructionReturnMessage;
            }
            else
            {
                IMethodCallMessage callMsg = msg as IMethodCallMessage;
                IMessage message;

                var attributes = callMsg.MethodBase.GetCustomAttributes(true);
                var datas = callMsg.MethodBase.GetCustomAttributesData();

                List<AttributeInof> list = new List<AttributeInof>();

                foreach(Attribute attribute in attributes)
                {
                    var data=datas.FirstOrDefault(x => x.AttributeType==attribute.GetType());

                    if (data == null) continue;

                    if(!data.NamedArguments.Any(x=>x.MemberName== "Order")|| !data.NamedArguments.Any(x => x.MemberName == "Sort"))
                    {
                        continue;
                    }

                    int Order = Convert.ToInt32(data.NamedArguments.FirstOrDefault(x => x.MemberName == "Order").TypedValue.Value);
                    ExecuteTime time = (ExecuteTime)Enum.ToObject(typeof(ExecuteTime), Convert.ToInt32(data.NamedArguments.FirstOrDefault(x => x.MemberName == "Sort").TypedValue.Value));

                    AttributeInof info = new AttributeInof();
                    info.Order = Order;
                    info.Time = time;
                    info.AttributeName = attribute.GetType().Name;
                    info.Datas = data.NamedArguments;
                    list.Add(info);
                }


                try
                {
                    //执行前
                    BeforeRun(list, callMsg.Args);

                    object[] args = callMsg.Args;
                    object o = callMsg.MethodBase.Invoke(GetUnwrappedServer(), args);

                    //执行后
                    AfterRun(list, callMsg.Args);

                    list.Clear();
                    list = null;

                    message = new ReturnMessage(o, args, args.Length, callMsg.LogicalCallContext, callMsg);
                }
                catch (Exception e)
                {
                    message = new ReturnMessage(e, callMsg);
                }
                return message;
            }
        }

        private void BeforeRun(List<AttributeInof> list, object[] args)
        {
            var attributes = list.Where(x => x.Time == ExecuteTime.BeforeRun).OrderBy(x => x.Order);
            if (attributes == null || attributes.Count() == 0)
            {
                return;
            }

            foreach(var attribute in attributes)
            {
                Dictionary<string, object> dict = new Dictionary<string, object>();

                foreach(var data in attribute.Datas)
                {
                    dict[data.MemberName] = data.TypedValue.Value;
                }
                Run(attribute.AttributeName, dict);
                dict.Clear();
                dict = null;
            }
        }

        private void AfterRun(List<AttributeInof> list, object[] args)
        {
            var attributes = list.Where(x => x.Time == ExecuteTime.AfterRun).OrderBy(x => x.Order);
            if (attributes == null || attributes.Count() == 0)
            {
                return;
            }

            foreach (var attribute in attributes)
            {
                Dictionary<string, object> dict = new Dictionary<string, object>();

                foreach (var data in attribute.Datas)
                {
                    dict[data.MemberName] = data.TypedValue.Value;
                }
                Run(attribute.AttributeName, dict);
                dict.Clear();
                dict = null;
            }
        }

        void Run(string attributeName,Dictionary<string,object> dict)
        {
            //此处可做成插件 根据配置的插件反射执行
            if (attributeName == "LogAttribute")
            {
                Log.Logs(dict);
            }
            else if (attributeName == "PermissionsAttribute")
            {
                Permission.Logs(dict);
            }
            else if (attributeName == "PerformanceAttribute")
            {
                Performance.Logs(dict);
            }
        }
    }

处理部分
    public class Log
    {
        public static void Logs(Dictionary<string,object> dict)
        {
            Console.WriteLine("日志记录");
        }
    }


    public class Permission
    {
        public static void Logs(Dictionary<string, object> dict)
        {
            Console.WriteLine("权限");
        }
    }

    public class Performance
    {
        public static void Logs(Dictionary<string, object> dict)
        {
            Console.WriteLine("性能统计");
        }
    }

Demo


[Aspect]
    public class SimpleDemo : ContextBoundObject
    {
        [Log(FunctionCode ="Hello",Sort =ExecuteTime.BeforeRun,Order =0)]
        [Permissions(FunctionCode = "Hello",Sort =ExecuteTime.BeforeRun,Order =1)]
        [Performance(Sort =ExecuteTime.AfterRun,Order =0)]
        public string Hello()
        {
            return "Hello World";
        }
    }


    public class ChildDemo : SimpleDemo
    {
        [Performance(Sort = ExecuteTime.AfterRun, Order = 0)]
        public void Say()
        {
            Console.WriteLine("我是 child");
        }
    }

测试
static void Main(string[] args)
        {
            SimpleDemo simple = new SimpleDemo();
            simple.Hello();

            ChildDemo child = new ChildDemo();
            child.Hello();
            child.Say();
            Console.Read();
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值