zoukankan      html  css  js  c++  java
  • .net Aop 实现原理

    本文实现所有继承BaseModel的类都通过代理拦截

    using System;
    using System.Reflection;
    using System.Collections.Generic;
    using System.Runtime.Remoting.Proxies;
    using System.Runtime.Remoting.Messaging;
    using System.Runtime.Remoting.Activation;
    
    namespace Soffice.DevelopFramework.Common.DataAccess
    {
        [AopAttribute]
        public class BaseModel : ContextBoundObject
        {
            private Dictionary<string, object> Fields = new Dictionary<string, object>();
    
            public void AddField(string fieldName, object value)
            {
                Fields.Add(fieldName, value);
            }
    
            public Dictionary<string, object> GetFields()
            {
                return Fields;
            }
        }
    
        class AopAttribute : ProxyAttribute
        {
            public override MarshalByRefObject CreateInstance(Type serverType)
            {
                AopProxy realProxy = new AopProxy(serverType);
                return realProxy.GetTransparentProxy() as MarshalByRefObject;
            }
        }
    
        class AopProxy : RealProxy
        {
            MethodInfo method = null;
            public AopProxy(Type serverType)
                : base(serverType)
            {
                method = serverType.GetMethod("AddField");
            }
            public override IMessage Invoke(IMessage msg)
            {
                //消息拦截之后,就会执行这里的方法。
                if (msg is IConstructionCallMessage) // 如果是构造函数,按原来的方式返回即可。
                {
                    IConstructionCallMessage constructCallMsg = msg as IConstructionCallMessage;
                    IConstructionReturnMessage constructionReturnMessage = this.InitializeServerObject((IConstructionCallMessage)msg);
                    RealProxy.SetStubData(this, constructionReturnMessage.ReturnValue);
                    return constructionReturnMessage;
                }
                else if (msg is IMethodCallMessage) //如果是方法调用(属性也是方法调用的一种)
                {
                    IMethodCallMessage callMsg = msg as IMethodCallMessage;
                    object[] args = callMsg.Args;
                    IMessage message;
                    try
                    {
                        if (callMsg.MethodName.StartsWith("set_") && args.Length == 1)
                        {
                            //这里检测到是set方法,然后应怎么调用对象的其它方法呢?
                            method.Invoke(GetUnwrappedServer(), new object[] { callMsg.MethodName.Substring(4), args[0] });//对属性进行调用
                        }
                        object o = callMsg.MethodBase.Invoke(GetUnwrappedServer(), args);
                        message = new ReturnMessage(o, args, args.Length, callMsg.LogicalCallContext, callMsg);
                    }
                    catch (Exception e)
                    {
                        message = new ReturnMessage(e, callMsg);
                    }
                    return message;
                }
                return msg;
            }
        }
    }
  • 相关阅读:
    JavaScript (三) js的基本语法
    JavaScript (二) js的基本语法
    JavaScript (一) js的介绍及基本语法变量
    Spring事务管理
    python静态方法、类方法
    python多继承
    python面向对象
    python模块(4)
    python模块(3)
    python模块(2)
  • 原文地址:https://www.cnblogs.com/weiweithe/p/4522642.html
Copyright © 2011-2022 走看看