代码改变世界

AOP之PostSharp5-LocationInterceptionAspect

2011-12-11 14:50  破狼  阅读(2214)  评论(2编辑  收藏  举报

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

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

代码:

[LazyLoad("test""test")] 
       private string TestField;

编译后:

image

我们在来看看LocationInterceptionAspect定义:

image

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

image

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

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

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

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

View Code
[Serializable] 
   public class LazyLoadAttribute : LocationInterceptionAspect 
   { 
       public string MethodName 
       { 
           get
           private set
       } 

       public string PrivoderFullName 
       { 
           get
           private set
       } 

       public LazyLoadAttribute(string MethodName, string PrivoderFullName) 
       { 
           Green.Utility.Guard.ArgumentNotNullOrEmpty(MethodName, "MethodName"); 
           Green.Utility.Guard.ArgumentNotNullOrEmpty(PrivoderFullName, "PrivoderFullName"); 
           this.MethodName = MethodName; 
           this.PrivoderFullName = PrivoderFullName; 
       } 

       public override void OnGetValue(LocationInterceptionArgs args) 
       { 
           if (args.GetCurrentValue() == null
           { 
               Console.WriteLine("Loading...."); 
               var value = this.LoadProperty(args.Instance); 
               if (value != null
               {                    
                   args.Value = value; 
                   args.ProceedSetValue(); 
               } 
           } 
           args.ProceedGetValue(); 
       } 

       private object LoadProperty(object p) 
       { 
           var type = Type.GetType(this.PrivoderFullName);//具体加载程序集需要自定义需求,这里仅为了测试简化。 
           if (type != null
           { 
               var method = type.GetMethod(this.MethodName); 
               if (method != null
               { 
                   object[] ps = null
                   if (p != null
                   { 
                       ps = new object[] { p }; 
                   } 
                   object entity = null
                   if (!method.IsStatic) 
                   { 
                       entity = System.Activator.CreateInstance(type); 
                   } 
                   return method.Invoke(entity, ps); 
               } 
           } 
           return null
       } 
   }
测试code:
View Code
class Program 
   {       
       static void Main(string[] args) 
       {            

           /* 
            * demo4
*/ 

           Student stu = new Student(); 
           stu.ID = 10
           Console.WriteLine(stu.Name); 
           Console.WriteLine(stu.Name); 

           Console.WriteLine(Student.TestStaticProperty); 
           Console.WriteLine(Student.TestStaticProperty); 
           Console.Read(); 
       }

public static string TextLazyLoadStaticMenthod(Student stu) 
      { 
          return "Student" + stu.ID; 
      } 

      public string TextLazyLoadInstacnceMenthod(Student stu) 
      { 
          return "Student" + stu.ID; 
      } 

      public string TextLazyLoadStaticPropertyMenthod() 
      { 
          return "测试"
      } 
  }

public class Student 
   { 
      // [LazyLoad("TextLazyLoadStaticMenthod", "PostSharpDemo.Program,PostSharpDemo")] 
       [LazyLoad("TextLazyLoadInstacnceMenthod""PostSharpDemo.Program,PostSharpDemo")] 
       public string Name 
       { getset; } 
       public string Sex 
       { getset; } 

       [LazyLoad("TextLazyLoadStaticPropertyMenthod""PostSharpDemo.Program,PostSharpDemo")] 
       public static string TestStaticProperty 
       { getset; } 

       public int ID 
       { getset; } 
   }
效果图片如下:

QQ截图未命名

附件下载:dmeo

  • AOP之PostSharp初见-OnExceptionAspect
  • AOP之PostSharp2-OnMethodBoundaryAspect
  • AOP之PostSharp3-MethodInterceptionAspect
  • AOP之PostSharp4-实现类INotifyPropertyChanged植入
  • AOP之PostSharp5-LocationInterceptionAspect
  • AOP之PostSharp6-EventInterceptionAspect
  • http://www.cnblogs.com/whitewolf/category/312638.html
  •