C#利用Attribute实现简易AOP介绍
首先看一段简单的代码:
| public partial class Form1 : Form |
| { |
| public Form1() |
| { |
| InitializeComponent(); |
| } |
| //来自UI层的调用 |
| private void button1_Click(object sender, EventArgs e) |
| { |
| BusinessHandler handler = new BusinessHandler(); |
| handler.DoSomething(); |
| } |
| } |
| //业务层的类和方法 |
| public class BusinessHandler |
| { |
| public void DoSomething() |
| { |
| MessageBox.Show("执行了方法本身!"); |
| } |
| } |
那么假设这是一个web程序,我们想在按钮点击时,先校验session,然后检验权限、起事务、写日志,然后再执行操作本身,最后再写日志。显然不能把对上面这些操作的方法调用都写在DoSomething()里,这样代码会变成一大坨屎,那我们该怎么办呢?
所谓AOP(面向切面编程)这个唬人的名词就是干这件事用的,其实现方式有很多种,比如利用Spring等框架,但是在实际项目中并不是想引一个框架进来就能随便引的,很多时候都需要我们自己手写一些机制。
这里想到了MVC当中的Filter,只要在Controller或者Action上打一个特性标签(Attribute),就能在方法执行前后做一些其他事情了。那么我们就来简单模拟一个Filter的实现吧。
首先给原先的方法改造一下,改成特性标签这种优雅的方式:
| //业务层的类和方法,让它继承自上下文绑定类的基类 |
| [MyInterceptor] |
| public class BusinessHandler : ContextBoundObject |
| { |
| [MyInterceptorMethod] |
| public void DoSomething() |
| { |
| MessageBox.Show("执行了方法本身!"); |
| } |
| } |
有了特性标签自然就要有特性标签对应的类,以及AOP的实现方法,这些东西可以单独独立到一个文件或程序集里。
首先是贴在方法上的标签,实现为空:
| //贴在方法上的标签 |
| [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] |
| public sealed class MyInterceptorMethodAttribute : Attribute { } |
之后定义贴在类上的标签:
| //贴在类上的标签 |
| [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] |
| public sealed class MyInterceptorAttribute : ContextAttribute, IContributeObjectSink |
| { |
| public MyInterceptorAttribute() |
| : base("MyInterceptor") |
| { } |
| //实现IContributeObjectSink接口当中的消息接收器接口 |
| public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink next) |
| { |
| return new MyAopHandler(next); |
| } |
| } |
这里定义了一个MyAopHandler类,实现如下:
| //AOP方法处理类,实现了IMessageSink接口,以便返回给IContributeObjectSink接口的GetObjectSink方法 |
| public sealed class MyAopHandler : IMessageSink |
| { |
| //下一个接收器 |
| private IMessageSink nextSink; |
| public IMessageSink NextSink |
| { |
| get { return nextSink; } |
| } |
| public MyAopHandler(IMessageSink nextSink) |
| { |
| this.nextSink = nextSink; |
| } |
| //同步处理方法 |
| public IMessage SyncProcessMessage(IMessage msg) |
| { |
| IMessage retMsg = null; |
| //方法调用消息接口 |
| IMethodCallMessage call = msg as IMethodCallMessage; |
| //如果被调用的方法没打MyInterceptorMethodAttribute标签 |
| if (call == null || (Attribute.GetCustomAttribute(call.MethodBase, typeof(MyInterceptorMethodAttribute))) == null) |
| { |
| retMsg = nextSink.SyncProcessMessage(msg); |
| } |
| //如果打了MyInterceptorMethodAttribute标签 |
| else |
| { |
| MessageBox.Show("执行之前"); |
| retMsg = nextSink.SyncProcessMessage(msg); |
| MessageBox.Show("执行之后"); |
| } |
| return retMsg; |
| } |
| //异步处理方法(不需要) |
| public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) |
| { |
| return null; |
| } |
| } |
注意到上面的执行前后具体操作部分代码,相当于一个“代理类”,它实质上是改变了方法执行的上下文。可以用委托等面向对象程序结构把具体实现暴露给外部进行二次开发。
C#利用Attribute实现简易AOP介绍的更多相关文章
- C#利用Attribute实现简易AOP介绍 (转载)
地址:http://dotnet.9sssd.com/csbase/art/638 http://wayfarer.blog.51cto.com/1300239/279913 http://devel ...
- C#当中利用Attribute实现简易AOP
首先看一段简单的代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); } //来自UI层的调用 ...
- 利用.NET Core类库System.Reflection.DispatchProxy实现简易Aop
背景 Aop即是面向切面编程,众多Aop框架里Castle是最为人所知的,另外还有死去的Spring.NET,当然,.NET Core社区新秀AspectCore在性能与功能上都非常优秀,已经逐渐被社 ...
- Aop介绍及几种实现方式
Aop介绍 我们先看一下wiki百科的介绍 Traditional software development focuses on decomposing systems into ...
- Spring AOP介绍及源码分析
转自:http://www.uml.org.cn/j2ee/201301102.asp 软件开发经历了从汇编语言到高级语言和从过程化编程到面向对象编程:前者是为了提高开发效率,而后者则使用了归纳法,把 ...
- Spring AOP编程(一)-AOP介绍
1. AOP介绍 l 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术 ...
- Spring AOP介绍与使用
Spring AOP介绍与使用 AOP:Aspect Oriented Programming 面向切面编程 OOP:Object Oriented Programming 面向对象编程 面向切面 ...
- C#利用Emit反射实现AOP,以及平台化框架封装思路
C#利用Emit反射实现AOP,以及平台化框架封装思路 这是前两天扒的一段动态代理AOP代码,用的Emit反射生成子类来实现代理模式,在这里做个小笔记,然后讨论一下AOP框架的实现思路. 首先是主函数 ...
- 利用基于@AspectJ的AOP实现权限控制
一. AOP与@AspectJ AOP 是 Aspect Oriented Programming 的缩写,意思是面向方面的编程.我们在系统开发中可以提取出很多共性的东西作为一个 Aspect,可以理 ...
随机推荐
- oracle drop table(表)数据恢复方法
今天不小心把系统用户表给drop掉了,正在运行的系统正式库啊,还好可以恢复 一.查看数据库回收站,看删除的表是否还在回收站select object_name,original_name,partit ...
- 详解Ajax请求(三)——jQuery对Ajax的实现及serialize()函数对于表单域控件参数提交的使用技巧
原生的Ajax对于异步请求的实现并不好用,特别是不同的浏览器对于Ajax的实现并不完全相同,这就意味着你使用原生的Ajax做异步请求要兼顾浏览器的兼容性问题,对于java程序员来讲这是比较头疼的事情, ...
- RxJava系列1(简介)
RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...
- python CSS
CSS 一. css的四种引入方式 1.行内式 2.嵌入式 3. 链接式 将一个.css文件引入到HTML文件中 1 <link href="mystyle.css" ...
- mysql 千万级数据查询效率实践,分析 mysql查询优化实践--本文只做了一部分,仅供参考
数据量, 1300万的表加上112万的表 注意: 本文只做了部分优化,并不全面,仅供参考, 欢迎指点. 请移步tim查看,因为写的时候在tim写的,粘贴过来截图有问题,就直接上链接了. https ...
- python 元组(tuple)的使用方法介绍
一.元组定义 元组和列表类似,元组使用的是小括号,列表是中括号,但是元组不像列表那样可以增删改:如果列表中存在列表或字符串,那么可以对其进行修改. 创建一个元组,只需要括号中添加元素,元素用逗号隔开即 ...
- ionic轮播图
根据自带的滑动图,只需要添加加红字体 <ion-view view-title="活动详情" class="align-title-center"> ...
- [LeetCode] Teemo Attacking 提莫攻击
In LLP world, there is a hero called Teemo and his attacking can make his enemy Ashe be in poisoned ...
- IOS开发---视频录制
今天研究了一下使用app录制视频的功能,感觉还是挺简单的.使用了AVFoundation框架,代码比较死,按步骤调用就行. 分享一下今天做的Demo的步骤 一,初始化输入设备,这里涉及到前,后摄像头: ...
- 线段树——codevs 1690 开关灯
先来一发题目: 1690 开关灯 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点 ...