zoukankan      html  css  js  c++  java
  • 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
    }
  • 相关阅读:
    windows笔记进程的句柄
    windows笔记创建线程的函数CreateThread
    c#实现从其他网站抓取imei码信息,手工输入验证码
    Linux下自动修改用户密码的方法(直接通过命令而不是在终端输入密码)
    Redis学习笔记List数据类型
    在Linux(centos)上安装PHP的mongodb扩展
    CI(codeigniter)如何防止sql注入
    MongoDB增加用户认证: 增加用户、删除用户、修改用户密码、读写权限、只读权限
    Sublime Text编辑器如何显示顶部的菜单栏
    C#图片选择器
  • 原文地址:https://www.cnblogs.com/nanfei/p/6386250.html
Copyright © 2011-2022 走看看