HTML5技术

.Net中的AOP系列之《拦截位置》 - tkb至简(6)

字号+ 作者:H5之家 来源:博客园 2016-08-30 18:00 我要评论( )

RaisePropertyChanged待会再实现。先来学习一下之前没有碰到过的PostSharp的API。args.GetCurrentValue获取当前的位置值,但是它还没有把值value放到args.Value。因此,这里把它存储在oldValue变量中再合适不过了。

RaisePropertyChanged待会再实现。先来学习一下之前没有碰到过的PostSharp的API。args.GetCurrentValue获取当前的位置值,但是它还没有把值value放到args.Value。因此,这里把它存储在oldValue变量中再合适不过了。args.Value返回即将到来的位置值。args.ProceedSetValue指示PostSharp允许继续set操作。
如果属性值发生了变化,那么我们就触发属性改变的事件。看一下传入的实参,args.Instance返回的是属性所在的对象(比如,NameViewModel类的实例),它应该是一个实现了INotifyPropertyChanged的类。args.LocationName返回被拦截的属性名,比如可能是FirstName或LastName。

当属性更改的通知发出之后,遍历所有指定的导出属性(如FullName),并为这些属性调用RaisePropertyChanged方法。下面我们完成最后这个切面并写完RaisePropertyChanged方法。在该方法中,你期望找到传入的实例对象上的PropertyChanged事件,并使用传入的位置名触发那个事件。然而,只有纯粹的一个对象object传入,所以必须借助反射来处理:

private void RaisePropertyChanged(object instance, string propertyName) { var type = instance.GetType(); var propertyChanged = type.GetField("PropertyChanged", BindingFlags.Instance|BindingFlags.NonPublic); var handler = propertyChanged.GetValue(instance) as PropertyChangedEventHandler; handler(instance,new PropertyChangedEventArgs(propertyName)); }

这个方法中没使用任何PostSharp API,只有反射的API。反射会检索实例instance的类型,从该类型中可以找到PropertyChanged事件字段。使用那个字段可以调用事件。

这里使用发射,是因为从类外面触发事件的唯一方式就是反射了。这样做并不好,因为反射是一个缓慢的过程,这样编写切面的话意味着属性每次改变时都会执行反射。此外,如果这个切面用在一个没有PropertyChanged事件的类上,那么就会报错。(解决办法请关注后面的教程,特别是PostSharp的CompileTimeValidate功能)

小结

这节我们覆盖了一个新的拦截类型:拦截属性和字段(位置)。和拦截方法一样,位置拦截切面扮演着getter/setter和处理getting/setting代码之间的中间人。

C#中的属性提供了简明的方式编写getter/setter方法,可以拦截方法的工具也可以拦截属性(比如Castle DynamicProxy)。但PostSharp为位置提供了一个特殊的类,该API可以同时为属性和字段服务。和方法拦截一样,我们可以继续执行get/setca操作,也可以获得关于位置的信息(比如字段名和属性名),实例对象等等。

这节也引入了一个新的AOP工具——PropertyChanged.Fody,这个工具很专一,只做一件事,不像PostSharp和Castle DynamicProxy是通用框架。

现在,我们已经可以编写拦截方法、边界方法、拦截位置的切面了。但是学习AOP不仅仅是数量(可以少写代码),而且还有质量。下一篇我们看下如何将单元测试和切面结合起来。

posted @

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 升讯威微信营销系统开发实践:(3)中控服务器的设计 .Net 还是 Java? - sheng.chao

    升讯威微信营销系统开发实践:(3)中控服务器的设计 .Net 还是 Java

    2016-08-26 16:00

  • 开源:ASP.NET MVC+EF6+Bootstrap开发框架 - NFine

    开源:ASP.NET MVC+EF6+Bootstrap开发框架 - NFine

    2016-08-24 11:00

  • ASP.NET 关于GridView 表格重复列合并 - 小飞飞oo

    ASP.NET 关于GridView 表格重复列合并 - 小飞飞oo

    2016-08-23 10:02

  • 拥抱.NET Core,如何开发一个跨平台类库 (1) - KAnts

    拥抱.NET Core,如何开发一个跨平台类库 (1) - KAnts

    2016-08-08 14:00

网友点评