AOP编程和ASP.NET MVC

AOP(Aspect oriented programming)面向切面编程。说成切面不容易理解,代码哪里有切面?又不是三维物体。概念不管,我们从其思想来理解这个名词吧。 AOP的主要思想是把相同、相似的并且零散的逻辑抽离出来,统一处理;这样不仅维护起来方便,也让代码更加关注自己本身,清晰明了。

比如我们常见的权限检查、日志记录、异常处理等都是散乱在系统各个地方,比如发表一篇文章的代码:

  1. public void Post(Article article)
  2. {
  3. if(currentUser is null)
  4. throw new AuthException("您还没有登录");
  5. else
  6. ArticleManager.Save(article);
  7. }

本来一句话ArticleManager.Save就能搞定的事情,现在要加上if else 还要处理异常,代码显得异常难看也难以维护。假如换成

  1. [Authorize]
  2. public void Post(Article article)
  3. {
  4. ArticleManager.Save(article);
  5. }

用AuthroizeAttribute来处理权限问题,这样代码清晰很多,而且可以复用这个Attribute,这么好的思想就是AOP思想。
当然Attribute只是一种实现方式,Attribute也是调用Post方法前,通过反射得到Attribute,然后执行其代码,
平时我们用的最多的AOP就在ASP.NET MVC框架里,这个AuthorizeAttribute就是MVC自带的。我们可以重写他的一些方法达到自己想要的功能(比如权限等级等)。

再举一个处理异常的例子,如果我们有一个统一的处理异常的逻辑,那么就可以在逻辑代码里不用try/catch,而是直接throw exception,这会让代码更加整洁。
(PS:比不是说有了统一处理就再也不用try/catch了,有些异常该吃掉的还是要吃掉,这要看具体的业务需求。另外捕获不到的异常比如线程里的要注意catch。)
比如例子:

  1. public void Post(Article article)
  2. {
  3. if(String.IsNullOrEmpty(article.Title))
  4. {
  5. throw new ArgumentMissException("title");
  6. }
  7. ...
  8. ArticleManager.Save(article);
  9. }
  10. protected override void OnException(ExceptionContext filterContext)
  11. {
  12. //..异常处理代码
  13. }

而只要重写MVC提供好的OnException方法就能处理所有的异常,或者是展现给用户友好的错误界面,或者是发送异常日志都很方便,而不用在每个地方都写处理的代码。
延伸考虑一下,如果统一处理异常信息,那么对异常的善后处理的把握就要看异常类的设计和运用了。

另外,再看上面的代码,如果有多个地方需要Post(Article),但又完全不一致,可是字段检查是一致的,那就会造成字段检查的代码重复,这种情况要么用一个单独的方法来验证Article的有效性,然后各个地方调用,要么就用MVC提供的ModelBinder,这也是通过参数的Attribute来实现的AOP方法;MVC考虑的太周到了,不得不赞。

  1. public void Post([ArticleBinder]Article article)
  2. {
  3. //这里就不需要再写关于Article的验证代码了
  4. ArticleManager.Save(article);
  5. }
  6. public class ArticleBinderAttribute : CustomModelBinderAttribute
  7. {
  8. class ArticleBinder : IModelBinder
  9. {
  10. public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
  11. {
  12. //虽然自定义了binder很惬意,但这里获取参数值时就没有用Action的参数那么舒服了。
  13. var title = controllerContext.RouteData.Values["title"].ToString();
  14. if (string.IsNullOrEmpty(title))
  15. {
  16. throw new ArgumentNullException("title");
  17. }
  18. return new Article
  19. {
  20. Title = title
  21. };
  22. }
  23. }
  24. public override System.Web.Mvc.IModelBinder GetBinder()
  25. {
  26. return new ArticleBinder();
  27. }
  28. }

  

运用框架提供的AOP很简单也很惬意,但我们在用别人的框架时不能只做应用级程序员,我们要领会其思想,掌握其本质,明白其实现。
所幸,MVC是开源的,我们可以看他的源代码,关注提供AOP的地方。

代码的设计或者说框架的设计,总是想让代码写起来干净利落,松耦合,不拖泥带水。
所以清晰的设计就是从程序的开始,一步步规划其运行步骤,并在适当的地方提供一些供用户处理方法。框架就是把用户框在自己设定的圈子里,但又尽可能的给用户自由。
我们看MVC的大致流程,
1、从输入Url回车那一刻起,先是通过UrlRouting路由,来判断用户访问哪个Controller/Action;
2、通过controllerfactory获取具体的controller实例,用户可自定义factory。
3、通过actioninvoke调用action,在调用之前需要先获取action的filter,这些filter就是AOP的拦截器。用户都可以自定义各种filter(就是自定义的attribute)。
4、根据执行顺序执行action和filter,onactionexecuting、onactionexecuted等。
5、找到action对应的view,用户可自定义viewenginer。
6、呈现页面结束。

当出错的时候invoke的catch调用onexception的用户的实现。

我本想罗列一些MVC的源码,但感觉没必要,有心人自己去下载看吧。如果不清楚的可以加群交流。

就是这样简单,AOP的思想是想把和当前逻辑不相干的代码抽离的一种实现,我们如果追求代码的美感,就会更加在意整体代码的设计,AOP通常用于一个系统的外围搭建处。
只有我们把架子、外围都搭建的漂亮,代码写起来才更美。

【转载请注明出处】
 
分类: ASP.NET
标签: 设计模式

AOP编程和ASP.NET MVC的更多相关文章

  1. 从抽象谈起(三):AOP编程和ASP.NET MVC

    AOP(Aspect oriented programming)面向切面编程.说成切面不容易理解,代码哪里有切面?又不是三维物体.概念不管,我们从其思想来理解这个名词吧. AOP的主要思想是把相同.相 ...

  2. C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(上)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(上)),不对的地方欢迎指出与交流. 章节出自<Professional C# ...

  3. C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(中)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(中)),不对的地方欢迎指出与交流. 章节出自<Professional C# ...

  4. C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(下)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 41 ASP.NET MVC(下)),不对的地方欢迎指出与交流. 章节出自<Professional C# ...

  5. ASP.Net MVC开发基础学习笔记:四、校验、AJAX与过滤器

    一.校验 — 表单不是你想提想提就能提 1.1 DataAnnotations(数据注解) 位于 System.ComponentModel.DataAnnotations 命名空间中的特性指定对数据 ...

  6. ASP.Net MVC开发基础学习笔记(4):校验、AJAX与过滤器

    一.校验 — 表单不是你想提想提就能提 1.1 DataAnnotations(数据注解) 位于 System.ComponentModel.DataAnnotations 命名空间中的特性指定对数据 ...

  7. 转:ASP.Net MVC:校验、AJAX与过滤器

    原文地址:http://blog.jobbole.com/85005/ 一.校验 — 表单不是你想提想提就能提 1.1 DataAnnotations(数据注解) 位于 System.Componen ...

  8. 基于ASP.NET MVC的热插拔模块式开发框架(OrchardNoCMS)--AOP编程

    AOP编程在目前来说好像是大家都比较喜欢的.ASP.NET MVC中的Filter就是使用AOP实现的配置器模式.AOP在编码中的应用主要有如下几个方面: 日志记录,跟踪,优化和监控 事务的处理 持久 ...

  9. ASP.NET MVC学前篇之扩展方法、链式编程

    ASP.NET MVC学前篇之扩展方法.链式编程 前言 目的没有别的,就是介绍几点在ASP.NETMVC 用到C#语言特性,还有一些其他琐碎的知识点,强行的划分一个范围的话,只能说都跟MVC有关,有的 ...

随机推荐

  1. 【百度地图API】如何区分地址解析和智能搜索?

    原文:[百度地图API]如何区分地址解析和智能搜索? 摘要: 很多用户一直无法区分地址解析geocoder和智能搜索localsearch的使用场景.该文章用一个详尽的示例,充分展示了这两个类,共5种 ...

  2. 【百度地图API】如何制作可拖拽的沿道路测距

    原文:[百度地图API]如何制作可拖拽的沿道路测距 摘要: 地图测距,大家都会,不就map.getDistance麼.可是,这只能测任意两点的直线距离,用途不够实际啊.比如,我想测试北京天安门到北京后 ...

  3. OC的构造方法与分类知识点总结

    OC语言构造方法: 用来初始化对象的方法,对象方法,以减号开头 为了让对象创建出来,成员变量就会有一些固定的值 重写构造方法的注意点: 先调用父类的构造方法([super init]) 再进行子类内部 ...

  4. 一个意想不到的CDO.Message 错误

    原文:一个意想不到的CDO.Message 错误   几个月之前,写了一个服务从MSMQ取消息发群发邮件的程序,一直也没时间测试,今日一试,出现发送邮件时报错,异常情况如下:   "Syst ...

  5. 为Pythonic论坛添加一个“专题”功能(续)

    上篇博文<为Pythonic论坛添加一个“专题”功能>,在模板的层次上对发帖进行了限制.也就是根据用户是否拥有权限来决定是否显示发帖框. 但是自从这么“投机取巧”的写完模板后,整夜辗转反侧 ...

  6. 初识Python-web框架的这两天

    前段时间打算学习python,其实时间蛮紧张的,看看文字教程,累了就看视频教程.算是把基本的语法过了一遍,但是OOP就费了好大的气力 ,C里有的对象,继承,等等等,还算能理解.不过高级点的就理解起来吃 ...

  7. js获取编辑框游标的位置

    代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...

  8. js获取最近几天的日期(转载)

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  9. windows下架设SVN服务器并设置开机启动

    原文:windows下架设SVN服务器并设置开机启动 1.安装SVN服务器,到http://subversion.apache.org/packages.html上下载windows版的SVN,并安装 ...

  10. Google Hacking的实现以及应用

    Google Hacking其实并算不上什么新东西,在早几年我在一些国外站点上就看见过相关的介绍,但是由于当时并没有重视这种技术,认为最多就只是用来找找未改名的mdb或者别人留下的webshell什么 ...