首页 > 学院 > 开发设计 > 正文

利用AOP写2PC框架(一)

2019-11-17 02:53:33
字体:
来源:转载
供稿:网友

利用AOP写2PC框架(一)

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

整个流程如下图:

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

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

    public interface IAopProxy    {        AopProxyBase CreateAopProxyInstance(MarshalByRefObject obj, Type type);    }
View Code

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

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,代码如下:

[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,代码如下:

 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去做一些拦截,记录的工作。


上一篇:C# Lambda &amp;&amp; Linq

下一篇:log4net入门

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表