这节我们要讨论的是PostSharp的LocationInterceptionAspect,PostSharp官方把Property和Field成为Location。所以LocationInterceptionAspect就是为了实现Property和Field的拦截。在我们前面讨论了关于方法OnMethodBoundaryAspect的aspect,我们很容易想到,在c#中Property就是一个编译时分为Get和Set两个方法,对于property的aspect就类似于了我们的Method的aspect。而对于Field的aspect同样可以转换为对Property的aspect。

下面我们用反编译工具来证实一下我的说法.

代码

 

  1. [LazyLoad("test""test")]   
  2.        private string TestField;  

编译后:

 

我们在来看看LocationInterceptionAspect定义:

其OnGetvalue和OnSetValue是我们主要拦截的方法,起参数LocationInterceptionArgs定义:

同样给也拥有来自父类AdviceArgs的Instance对象,对于对象级Location为所在对象,静态则为null;

LocationInterceptionAspect的使用方法和我们的OnMethodBoundaryAspect和类似,使用方式也一样,对于使用对不重要,鄙人觉得更重要的是我们的设计思想。

我暂时能想到的很好的LocationInterceptionAspect使用场景则是LazyLoad,对于3.5表达式的出现,我们到处都可以简单这个词,在c#类库中也加入了这个类。

这里我们只是做一个简单的演示demo,根据attribute上制定的类型的方法延时加载对象,废话不说了上code:

  1. View Code   
  2.  
  3. [Serializable]   
  4.    public class LazyLoadAttribute : LocationInterceptionAspect   
  5.    {   
  6.        public string MethodName   
  7.        {   
  8.            get;   
  9.            private set;   
  10.        }   
  11.  
  12.        public string PrivoderFullName   
  13.        {   
  14.            get;   
  15.            private set;   
  16.        }   
  17.  
  18.        public LazyLoadAttribute(string MethodName, string PrivoderFullName)   
  19.        {   
  20.            Green.Utility.Guard.ArgumentNotNullOrEmpty(MethodName, "MethodName");   
  21.            Green.Utility.Guard.ArgumentNotNullOrEmpty(PrivoderFullName, "PrivoderFullName");   
  22.            this.MethodName = MethodName;   
  23.            this.PrivoderFullName = PrivoderFullName;   
  24.        }   
  25.  
  26.        public override void OnGetValue(LocationInterceptionArgs args)   
  27.        {   
  28.            if (args.GetCurrentValue() == null)   
  29.            {   
  30.                Console.WriteLine("Loading....");   
  31.                var value = this.LoadProperty(args.Instance);   
  32.                if (value != null)   
  33.                {                      
  34.                    args.Value = value;   
  35.                    args.ProceedSetValue();   
  36.                }   
  37.            }   
  38.            args.ProceedGetValue();   
  39.        }   
  40.  
  41.        private object LoadProperty(object p)   
  42.        {   
  43.            var type = Type.GetType(this.PrivoderFullName);//具体加载程序集需要自定义需求,这里仅为了测试简化。   
  44.            if (type != null)   
  45.            {   
  46.                var method = type.GetMethod(this.MethodName);   
  47.                if (method != null)   
  48.                {   
  49.                    object[] ps = null;   
  50.                    if (p != null)   
  51.                    {   
  52.                        ps = new object[] { p };   
  53.                    }   
  54.                    object entity = null;   
  55.                    if (!method.IsStatic)   
  56.                    {   
  57.                        entity = System.Activator.CreateInstance(type);   
  58.                    }   
  59.                    return method.Invoke(entity, ps);   
  60.                }   
  61.            }   
  62.            return null;   
  63.        }   
  64.    }  
  65. 复制代码  

测试code:

  1. View Code   
  2.  
  3. class Program   
  4.    {         
  5.        static void Main(string[] args)   
  6.        {              
  7.  
  8.            /*   
  9.             * demo4*/   
  10.  
  11.            Student stu = new Student();   
  12.            stu.ID = 10;   
  13.            Console.WriteLine(stu.Name);   
  14.            Console.WriteLine(stu.Name);   
  15.  
  16.            Console.WriteLine(Student.TestStaticProperty);   
  17.            Console.WriteLine(Student.TestStaticProperty);   
  18.            Console.Read();   
  19.        }  
  20.  
  21. public static string TextLazyLoadStaticMenthod(Student stu)   
  22.       {   
  23.           return "Student" + stu.ID;   
  24.       }   
  25.  
  26.       public string TextLazyLoadInstacnceMenthod(Student stu)   
  27.       {   
  28.           return "Student" + stu.ID;   
  29.       }   
  30.  
  31.       public string TextLazyLoadStaticPropertyMenthod()   
  32.       {   
  33.           return "测试";   
  34.       }   
  35.   }  
  36.  
  37. public class Student   
  38.    {   
  39.       // [LazyLoad("TextLazyLoadStaticMenthod""PostSharpDemo.Program,PostSharpDemo")]   
  40.        [LazyLoad("TextLazyLoadInstacnceMenthod""PostSharpDemo.Program,PostSharpDemo")]   
  41.        public string Name   
  42.        { get; set; }   
  43.        public string Sex   
  44.        { get; set; }   
  45.  
  46.        [LazyLoad("TextLazyLoadStaticPropertyMenthod""PostSharpDemo.Program,PostSharpDemo")]   
  47.        public static string TestStaticProperty   
  48.        { get; set; }   
  49.  
  50.        public int ID   
  51.        { get; set; }   
  52.    }  
  53. 复制代码 

效果图片如下:

附件下载:dmeo