国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

自己實現簡單的AOP(二)引入Attribute為方法指定增強對象

2019-11-14 15:50:33
字體:
來源:轉載
供稿:網友

話續前文 : 自己實現簡單的AOP(一)簡介 

 

在前一篇文章中,對AOP的實現方式做了一個簡單介紹。接下來,引入Attribute 為方法指定增強對象,由此實現一個簡單的AOP。

注意:指定的是增強對象,“對象”,也就是說Attribute標記,標記的其實是一個對象。由此、使用多態便可輕松實現增強的擴展。

 

自定義的Attribute 

    /// <summary>    /// 為方法標記指定的增強對象    /// <para>指定的增強,可通過代理 DelayPRoxy 織入</para>    /// </summary>    [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]    public sealed class AdviceAttribute : Attribute    {        /// <summary>        /// 增強對象        /// </summary>        public AdviceAbstract Advice { get; private set; }        /// <summary>        /// 使用指定類型的默認增強對象        /// <para>如果類型為空 則不使用任何增強</para>        /// </summary>        /// <param name="type"></param>        public AdviceAttribute(Type type)            : this(type, string.Empty)        {        }        /// <summary>        /// 使用公有靜態方法名初始化指定類型的增強對象        /// <para>如果類型為空 則不使用任何增強</para>        /// </summary>        /// <param name="type">類型</param>        /// <param name="methodName">        /// 公有靜態方法名        /// <para>如果方法名為空,調用默認構造函數</para>        /// </param>        public AdviceAttribute(Type type, string methodName)        {            // 如果類型為空 則不使用任何增強            if (type == null)            {                this.Advice = null;                return;            }            if (string.IsNullOrWhiteSpace(methodName))            {                this.Advice = Activator.CreateInstance(type) as AdviceAbstract;                return;            }            this.Advice = type.InvokeMember(                methodName,                System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public                | System.Reflection.BindingFlags.Static,                null, null, null) as AdviceAbstract;        }        #region 以下兩種方式效果不是很好,不推薦使用,故 構造函數私有化        /// <summary>        /// 使用參數列表初始化指定類型的增強對象        /// </summary>        /// <param name="type">類型</param>        /// <param name="objs">參數列表</param>        private AdviceAttribute(Type type, params object[] objs)        {            this.Advice = Activator.CreateInstance(type, objs) as AdviceAbstract;        }        /// <summary>        /// 使用命名參數初始化指定類型的增強對象        /// </summary>        /// <param name="namedParameter">        /// 以 冒號 和 分號 分割的形參的命名參數列表        /// <para>支持的數據類型有:string, int, bool 及 可通過靜態方法Parse 反序列化的類型</para>        /// </param>        /// <param name="type"></param>        private AdviceAttribute(string namedParameter, Type type)        {            this.Advice = ReflectionUtil.InvokeConstructor(type, namedParameter) as AdviceAbstract;        }        #endregion    }
Attribute

 

增強的抽象類 和 自定義的增強

    /// <summary>    /// 抽象的增強類    /// </summary>    public abstract class AdviceAbstract    {        public abstract IMessage Invoke(MarshalByRefObject target, IMethodCallMessage callMessage);    }    public class MyAdvice : AdviceAbstract    {        public override IMessage Invoke(MarshalByRefObject target, IMethodCallMessage callMessage)        {            this.BeforeInvoke(target);            IMessage message = DelayProxyUtil.InvokeBeProxy(target, callMessage);            this.AfterInvoke(target);            return message;        }        protected virtual void BeforeInvoke(MarshalByRefObject target)        {            Console.WriteLine("Before");        }        protected virtual void AfterInvoke(MarshalByRefObject target)        {            Console.WriteLine("After");        }    }
Advice

 

有了如上的兩個組件,再借助代理類 DelayProxy<T>,將增強織入,簡單的AOP就已經初具原形了。

    /// <summary>    /// 支持泛型、支持延遲初始化的代理類, 可為 MarshalByRefObject 的子類型提供代理    /// <para>在執行代理的過程中,獲取 AdviceAttribute 所指定的增強,并織入該增強</para>    /// </summary>    public class DelayProxy<T> : RealProxy where T : MarshalByRefObject    {        private static object objLock = new object();        /// <summary>        /// 被代理的對象        /// </summary>        private T target;        /// <summary>        /// 是否延遲初始化        /// <para>True:延遲, False: 不延遲</para>        /// </summary>        private readonly bool delay;        public DelayProxy(T target, bool delay)            : base(typeof(T))        {            this.target = target;            this.delay = delay;        }        /// <summary>        /// 調用被代理對象        /// <para>支持 out ref 參數</para>        /// </summary>        /// <param name="msg"></param>        /// <returns></returns>        public override IMessage Invoke(IMessage msg)        {            if (this.delay && this.target == null)            {                lock (objLock)                {                    if (this.delay && this.target == null)                    {                        T instance = Activator.CreateInstance(typeof(T)) as T;                        // 自動裝配屬性                        // 為屬性對象啟用代理,并延遲初始化被代理的對象                        // DelayProxyUtil.AutowiredProperties(instance);                        this.target = instance;                    }                }            }            IMethodCallMessage callMessage = (IMethodCallMessage)msg;            AdviceAttribute attri = ReflectionUtil.GetCustomAttribute<AdviceAttribute>(callMessage.MethodBase);            if (attri != null && attri.Advice != null)            {                return attri.Advice.Invoke(this.target, callMessage);            }            return DelayProxyUtil.InvokeBeProxy(this.target, callMessage);        }    }
DelayProxy

 

源碼(MVC4的項目 沒有packages文件夾):http://files.VEVb.com/files/08shiyan/AOPDemo.zip 

該源碼中還實現了被代理對象的延遲初始化。

 

未完待續...

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 修武县| 自贡市| 尤溪县| 德惠市| 汉源县| 土默特左旗| 朝阳县| 广河县| 永嘉县| 遂宁市| 子长县| 金溪县| 烟台市| 贡嘎县| 盈江县| 安龙县| 平顶山市| 秭归县| 和林格尔县| 陕西省| 安溪县| 保康县| 枝江市| 新密市| 新龙县| 手游| 江西省| 湛江市| 丘北县| 彭山县| 荣昌县| 徐闻县| 鄂托克旗| 阳曲县| 长武县| 锡林浩特市| 繁峙县| 汉寿县| 西畴县| 汉寿县| 合肥市|