C# 的AOP实现

闲来无事,做了一个AOP示例,此示例只能捕获方法调用事件,无法动态阻止方法调用的执行。因为取消后构造返回值成了难题,返回null貌似会报错。如果不需要这个功能,其实还是很完美的。

缺点是没有以接口方式实现,使用类必须继承ContextBoundObject。

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Messaging;

namespace Csharp实现AOP方法拦截
{
    #region AOP Helper

    public class MyApoAspect : IMessageSink
    {
        private IMessageSink _NextSink = null;
        private IMyAopMethodFilter _MethodFilter;

        internal MyApoAspect(IMessageSink msgSink, IMyAopMethodFilter methodFilter)
        {
            _NextSink = msgSink;
            _MethodFilter = methodFilter;
        }

        public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
        {
            IMessage message = this.SyncProcessMessage(msg);
            replySink.SyncProcessMessage(message);
            return null;

        }

        public IMessageSink  NextSink
        {
            get { return _NextSink; }
        }

        public IMessage SyncProcessMessage(IMessage msg)
        {
            var cancel = false;
            _MethodFilter.PreAopMethodFilter(msg,ref cancel);
            if (cancel)
            {
                //此处不知如何返回
                return null;
            }
            IMessage returnMethod = _NextSink.SyncProcessMessage(msg);
            _MethodFilter.PostAopMethodFilter(msg);
            return returnMethod;
        }
    }

    public class MyAopProperty: IContextProperty, IContributeObjectSink
    {
        private IMyAopMethodFilter _MethodFilter;

        public MyAopProperty(IMyAopMethodFilter methodFilter)
        {
            _MethodFilter = methodFilter;
        }

        public void  Freeze(Context newContext) { }

        public bool  IsNewContextOK(Context newCtx)
        {
            return true;
        }

        public string  Name
        {
            get 
            { 
                return "MyAopProperty";
            }
        }

        public IMessageSink  GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
        {
            return new MyApoAspect(nextSink, _MethodFilter);
        }
    }

    [AttributeUsage(AttributeTargets.Class)]
    public class MyAopAttribute : ContextAttribute, IMyAopMethodFilter
    {
        private IMyAopMethodFilter _MethodFilter;

        public MyAopAttribute() 
            : base("MyAopAttribute") 
        {
            _MethodFilter = this;
        }

        public override void GetPropertiesForNewContext(IConstructionCallMessage ccm)
        {
            ccm.ContextProperties.Add(new MyAopProperty(_MethodFilter));
        }

        protected virtual void OnPreAopMethodFilter(IMessage msg, ref bool Cancel)
        {
            throw new NotImplementedException();
        }

        protected virtual void OnPostAopMethodFilter(IMessage msg)
        {
            throw new NotImplementedException();
        }

        public void PreAopMethodFilter(IMessage msg ,ref bool Cancel)
        {
            this.OnPreAopMethodFilter(msg,ref Cancel);
        }

        public void PostAopMethodFilter(IMessage msg)
        {
            this.OnPostAopMethodFilter(msg);
        }
    }

    public interface IMyAopMethodFilter
    {
        void PreAopMethodFilter(IMessage msg, ref bool Cancel);
        void PostAopMethodFilter(IMessage msg);
    }

    #endregion

    #region AOP Demo

    public class Class1AopAttribute : MyAopAttribute
    {
        protected override void OnPreAopMethodFilter(IMessage msg, ref bool Cancel)
        {
            IMethodMessage call = msg as IMethodMessage;
            Type type = Type.GetType(call.TypeName);
            string callStr = type.Name + "." + call.MethodName;
            var args = call.Args;
            Console.WriteLine("在执行前拦截到" + callStr);
        }

        protected override void OnPostAopMethodFilter(IMessage msg)
        {
            IMethodMessage call = msg as IMethodMessage;
            Type type = Type.GetType(call.TypeName);
            string callStr = type.Name + "." + call.MethodName;
            var args = call.Args;
            Console.WriteLine("在执行后拦截到" + callStr);
        }
    }

    [Class1AopAttribute()]
    public class Class1:ContextBoundObject
    {
        public int A { get; set; }

        public int B(ref int p) 
        {
            p++;
            return p + 1;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Class1 c1 = new Class1();
            c1.A = 2;

            int p = 0;
            c1.B(ref p);

            Console.ReadLine();
        }
    }

    #endregion
}
复制代码

 

posted on   空明流光  阅读(1784)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示