AOP_02 通过ContextBoundObject、ContextAttribute 上下文对象实现

 主要用于 监听对象的标记

[AttributeUsage(AttributeTargets.Class)] public class AOPAttribute : ContextAttribute, IContributeObjectSink { // IContributeObjectSink :在远程处理调用的服务器端分配对象特定的侦听接收器, 这个地方监听到AOPAttribute标记的对象时,会执行GetObjectSink方法 public AOPAttribute() : base("Proxy") { } /// <summary> /// 获取上下文中的消息【方法】 /// </summary> /// <param name="obj"></param> /// <param name="nextSink"></param> /// <returns></returns> public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink) { return new MessageSink(nextSink); } }

主要 用于监听继承ContextBoundObject所有对象 

/// <summary>
    /// 任何一个需要应用上下文同步机制类的父类,
    /// 继承ContextBoundObject的子类实例称为上下文绑定对象,
    /// 而通常的类实例称为上下文灵活对象。上下文绑定的对象永远在其上下文中执行
    /// </summary>
    [AOP]  // 这里[Aop] 表示,继承AOPIntercept 所有的子类都会被监听,也可以在子类中打【aop】标签  ContextBoundObject 和ContextAttribute 配合使用
    public class AOPIntercept : ContextBoundObject
    {
        /* 通过ContextBoundObject来实现AOP,
         * 其中有大约60%的时间花在GetCustomAttribute的反射上,
         * 另外40%则是MarshalByRefObject(ContextBoundObject的基类,
         * 实际上ContextBoundObject什么事情都没做,只是单纯的继承了MarshalByRefObject)
         * 内部上下文管理上,它需要管理些啥呢?ContextBoundObject是一个上下文对象的基类
         * ,继承自它的子类将被一个特别的上下文管理起来,这个上下文包括一系列的属性集合或者规则,
         * 当进入或者离开上下文时,将强制执行规则。当使用ContextBoundObject实现AOP时,除了性能底下,
         * 其必须继承自ContextBoundObject,对于单继承的语言来讲可能带来不便。
         */

        // 继承 ContextBoundObject的所有子类,都会获取到上下文信息,
    }

  

  /// <summary>
    /// 监听消息
    /// </summary>
    public class MessageSink : IMessageSink
    {
        // 添加两个委托,用于监听执行前和执行后的过程
        public static event EventHandler<EventArgs> BeforeExcute;

        public static event EventHandler<EventArgs> AfterExcute;
  
        private IMessageSink _sink;
        public MessageSink(IMessageSink sink)
        {
            _sink = sink;
        }
        public IMessageSink NextSink => _sink;

        public IMessageCtrl AsyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage msg, IMessageSink replySink)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 以同步方式处理给定的消息 
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public System.Runtime.Remoting.Messaging.IMessage SyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage msg)
        {
            if (BeforeExcute != null)
                BeforeExcute.Invoke(msg.Properties,null);
             var message= _sink.SyncProcessMessage(msg); // 执行方法,并返回msg
            if (AfterExcute != null)
                AfterExcute.Invoke(msg.Properties, null);
            return message;
        }
       
    }

  

使用:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 代理
{
    class Program
    {
        static void Main(string[] args)
        {

            //IMessage message = new ProxyMessage();
            //message.SendMessage("hnzheng");






            // 注册监听
            MessageSink.BeforeExcute += BeforeExcute;
            MessageSink.AfterExcute += AfterExcute;
            TestAop testAop = new TestAop();
            testAop.TestMethod("1111");
        
            Console.ReadLine();


        }

        public static void BeforeExcute(object sender,EventArgs e)
        {
            Console.WriteLine(nameof(BeforeExcute));
        }
        public static void AfterExcute(object sender, EventArgs e)
        {
            Console.WriteLine(nameof(AfterExcute));
        }
        static void GetString(string name)
        {
            //  GetString(name);

        }
    }

    [AOP]
    public class TestAop: AOPIntercept
    {
        public void TestMethod(string name)
        {
            Console.WriteLine(name);
        }

    }
 

}

 

  结果:

 

 

缺点:

/* 通过ContextBoundObject来实现AOP,
* 实际上ContextBoundObject什么事情都没做,只是单纯的继承了MarshalByRefObject)
* 内部上下文管理上,ContextBoundObject是一个上下文对象的基类
* ,继承自它的子类将被一个特别的上下文管理起来,这个上下文包括一系列的属性集合或者规则,
* 当进入或者离开上下文时,将强制执行规则。当使用ContextBoundObject实现AOP时,除了性能底下,
* 其必须继承自ContextBoundObject,对于单继承的语言来讲可能带来不便。
*/

 

posted @ 2020-04-17 23:00  谁说程序猿很猥琐  阅读(310)  评论(0编辑  收藏  举报