利用AOP写2PC框架(一)

并不是很想写这个系列,因为这个2pc单独写一个小架构有点鸡肋。不过也不知道写什么了,先写了再说吧。

整个流程如下图:

利用AOP写2PC框架(一)

关于AOP系列的文章很多,我这里也再重复造一下轮子。

首先,我们定义了一个IAopProxy,用于给AopProxyFactory用来创建Proxy实例的接口,代码如下:

利用AOP写2PC框架(一)
    public interface IAopProxy

    {

        AopProxyBase CreateAopProxyInstance(MarshalByRefObject obj, Type type);

    }
View Code

AOP截获最重要的就是RealProxy类了,我们写一个AopProxyBase抽象类,继承于RealProxy,代码如下:

利用AOP写2PC框架(一)
public abstract class AopProxyBase : RealProxy

    {

        private readonly MarshalByRefObject target; //默认透明代理

        public AopProxyBase(MarshalByRefObject obj, Type type)

            : base(type)

        {

            this.target = obj;

        }



        public override IMessage Invoke(IMessage msg)

        {

            IMethodCallMessage call = (IMethodCallMessage)msg;



            bool isIntercept = false;



            var attrs = call.MethodBase.GetCustomAttributes(typeof(AopMethodAttribute), false) as AopMethodAttribute[];



            //如果标记了AopMethodAttribute的,才记录。

            if (attrs.Length > 0)

            {

                isIntercept = true;

            }

            

            if (isIntercept)

            {

                this.Before(msg, attrs);

            }



            //如果触发的是构造函数,此时target的构建还未开始

            IConstructionCallMessage ctor = call as IConstructionCallMessage;

            if (ctor != null)

            {

                //获取最底层的默认真实代理

                RealProxy default_proxy = RemotingServices.GetRealProxy(this.target);

                default_proxy.InitializeServerObject(ctor);

                MarshalByRefObject tp = (MarshalByRefObject)this.GetTransparentProxy();



                return EnterpriseServicesHelper.CreateConstructionReturnMessage(ctor, tp);

            }



            IMethodReturnMessage result_msg = RemotingServices.ExecuteMessage(this.target, call);



            if (isIntercept)

            {

                this.After(msg, result_msg, attrs);

            }



            return result_msg;

        }





        public abstract void Before(IMessage requestMsg, AopMethodAttribute[] attrs);



        public abstract void After(IMessage requestMsg, IMessage Respond, AopMethodAttribute[] attrs);



    }
View Code

同时,我们定义了AopAttribute : ProxyAttribute,代码如下:

利用AOP写2PC框架(一)
[AttributeUsage(AttributeTargets.Class)]

    public class AopAttribute : ProxyAttribute

    {

        IAopProxy proxy;

        public AopAttribute(Type factoryType)

        {

            this.proxy = (IAopProxy)AopProxyFactory.CreateInstance(factoryType);

        }



        public override MarshalByRefObject CreateInstance(Type serverType)

        {

            MarshalByRefObject target = base.CreateInstance(serverType);

            

            AopProxyBase rp = this.proxy.CreateAopProxyInstance(target, serverType);



            return (MarshalByRefObject)rp.GetTransparentProxy();

        }

    }
View Code

可以看到在AopAttribute的构造函数里面,有通过Factory去创建被拦截的Class的实例,避免每次都去创建,我加了一个Dictionary作为Cache,代码如下:

利用AOP写2PC框架(一)
 public class AopProxyFactory

    {

        private static AopProxyCache _proxyCollection;



        private static readonly object _syncObject = new object();

        static AopProxyFactory()

        {

            lock (_syncObject)

            {

                if (_proxyCollection == null)

                {

                    _proxyCollection = new AopProxyCache();

                }

            }

        }



        public static IAopProxy CreateInstance(Type type)

        {

            return _proxyCollection[type];

        }

    }







public class AopProxyCache

    {

        public Dictionary<Type, IAopProxy> _proxys;

        private static readonly object _syncObject = new object();



        public AopProxyCache()

        {

            lock (this)

            {

                if (_proxys == null)

                {

                    _proxys = new Dictionary<Type, IAopProxy>();

                }

            }

        }



        public void Add(Type type, IAopProxy proxy)

        {

            if (_proxys == null) throw new ArgumentNullException("proxys is not init");

            lock (_syncObject)

            {

                this._proxys[type] = proxy;

            }

        }



        public IAopProxy Get(Type type)

        {

            IAopProxy proxy;

            if (this._proxys.ContainsKey(type))

            {

                proxy = this._proxys[type];

            }

            else

            {

                lock(_syncObject)

                {

                    if (!this._proxys.ContainsKey(type))

                    {

                        proxy = (IAopProxy)Activator.CreateInstance(type);

                        this.Add(type, proxy);

                    }

                    else

                    {

                        proxy = this._proxys[type];

                    }

                }

            }

            return proxy;

        }



        public IAopProxy this[Type type]

        {

            get

            {

                return this.Get(type);

            }

            set

            {

                this.Add(type, value);

            }

        }

    }
View Code

那道这里Aop的基础类就搭建完毕了,具体的拦截后,要做什么,则需要去继承于我们的抽象类AopProxyBase,然后复写After和Before去做一些拦截,记录的工作。

 

你可能感兴趣的:(AOP)