利用Attribute实现Aop
Aop“面向切面编程”,与OOP“面向对象编程”一样是一种编程思路。个人理解:在不改变原有逻辑的基础上,注入其他行为。
基础代码(仿MVC拦截器实现)
namespace HGL.Toolkit.Aop
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class AopAttribute : ContextAttribute, IContributeObjectSink
{
public AopAttribute() : base("Aop") { } //实现IContributeObjectSink接口当中的消息接收器接口
public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink next)
{
return new AopProxy(next);
}
} [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class AopMethodAttribute : Attribute
{
/// <summary>
/// 方法执行之前,执行代码
/// </summary>
public virtual bool OnMethodExecuting(System.Web.HttpContext context)
{
return true;
} /// <summary>
/// 方法执行之后,执行代码
/// </summary>
public virtual bool OnMethodExecuted(System.Web.HttpContext context)
{
return true;
}
}
} namespace HGL.Toolkit.Aop
{
public sealed class AopProxy : IMessageSink
{
//下一个接收器
private IMessageSink nextSink; public IMessageSink NextSink
{
get { return nextSink; }
} public AopProxy(IMessageSink nextSink)
{
this.nextSink = nextSink;
} //同步处理方法
public IMessage SyncProcessMessage(IMessage msg)
{
IMessage retMsg = null; //方法调用消息接口
IMethodCallMessage call = msg as IMethodCallMessage; var attributes = Attribute.GetCustomAttributes(call.MethodBase, typeof(AopMethodAttribute)); //如果被调用的方法没打AopMethodAttribute标签
if (call == null || attributes.Count() == 0)
{
retMsg = nextSink.SyncProcessMessage(msg);
}
//如果打了AopMethodAttribute标签
else
{
foreach (var attribute in attributes)
{
var obj = attribute.GetType(); var executing = obj.GetMethod("OnMethodExecuting");
if (executing != null)
{
var context=System.Web.HttpContext.Current;
executing.Invoke(attribute, new object[] { context });
}
} retMsg = nextSink.SyncProcessMessage(msg); foreach (var attribute in attributes)
{
var obj = attribute.GetType(); var executed = obj.GetMethod("OnMethodExecuted");
if (executed != null)
{
var context = System.Web.HttpContext.Current;
executed.Invoke(attribute, new object[] { context });
}
}
} return retMsg;
} //异步处理方法(不需要)
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
return null;
}
}
}
使用注意:
1.使用到Aop的类必须继承ContextBoundObject
2.使用到Aop的方法存在的类必须添加[Aop]特性
3.哪个方法需要实现Aop,就给那个方法添加[AopMethod]特性 AopMethod未实现任何业务逻辑,使用者需要重写该attribute /// <summary>
/// 方法执行之前,执行代码
/// </summary>
public virtual bool OnMethodExecuting()
{
return true;
} /// <summary>
/// 方法执行之后,执行代码
/// </summary>
public virtual bool OnMethodExecuted()
{
return true;
}
待续......(将执行前和执行后的方法使用代理委托机制,实现二次开发)
利用Attribute实现Aop的更多相关文章
- C# Unity依赖注入利用Attribute实现AOP功能
使用场景? 很多时候, 我们定义一个功能, 当我们要对这个功能进行扩展的时候, 按照常规的思路, 我们一般都是利用OOP的思想, 在原有的功能上进行扩展. 那么有没有一种东西, 可以实现当我们需要扩展 ...
- C#.NET利用ContextBoundObject和Attribute实现AOP技术--AOP事务实现例子
我前两天看见同事用写了用AOP技术实现缓存的方案,于是好奇看了一下这是怎么实现的.原来是用了.NET中的一个类ContextBoundObject和Attribute相关技术.其实个类在.NET Fr ...
- 利用C#实现AOP常见的几种方法详解
利用C#实现AOP常见的几种方法详解 AOP面向切面编程(Aspect Oriented Programming) 是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 下面这篇文章主要 ...
- .Net core 2.0 利用Attribute获取MVC Action来生成菜单
最近在学习.net core的同时将老师的MVC5项目中的模块搬过来用,其中有一块就是利用Attribute来生成菜单. 一·首先定义Action实体 /// <summary> /// ...
- C#利用Attribute实现简易AOP介绍
首先看一段简单的代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); } //来自UI层的调用 ...
- C#当中利用Attribute实现简易AOP
首先看一段简单的代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); } //来自UI层的调用 ...
- C#利用Attribute实现简易AOP介绍 (转载)
地址:http://dotnet.9sssd.com/csbase/art/638 http://wayfarer.blog.51cto.com/1300239/279913 http://devel ...
- ssm+redis 如何更简洁的利用自定义注解+AOP实现redis缓存
基于 ssm + maven + redis 使用自定义注解 利用aop基于AspectJ方式 实现redis缓存 如何能更简洁的利用aop实现redis缓存,话不多说,上demo 需求: 数据查询时 ...
- 从Unity中的Attribute到AOP(七)
本章我们将依然讲解Unity中的Attribute,继续命名空间在UnityEngine里的. PropertyAttribute,这个特性主要来控制变量或者类在Inspector里面的显示方式.和P ...
随机推荐
- ActiveReports 9实战教程(2): 准备数据源(设计时、执行时)
在上讲中<ActiveReports 9实战教程(1): 手把手搭建好开发环境Visual Studio 2013 社区版>,我们已经结合Visual Studio 2013搭建好了Act ...
- 中科燕园GIS外包--移动GIS
移动GIS恰逢其时 得益于移动智能终端的普及和移动互联网的发展,伴随着GIS技术的发展和应用的深入.越来越多的企业和普通消费者開始体会到移动GIS的巨大潜力和价值. 移动GIS轻便灵活,受众面广.随时 ...
- POJ 2394 Dijkstra
题意: 思路: 裸的Dijkstra 爆敲一发模板 //By SiriusRen #include <queue> #include <cstdio> #include < ...
- channels
package main import ( "fmt" "time" "strconv") func pinger(c chan strin ...
- Atcoder AGC 019 A,B
A - Ice Tea Store Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement You' ...
- Gym 100952 G. The jar of divisors
http://codeforces.com/gym/100952/problem/G G. The jar of divisors time limit per test 2 seconds memo ...
- atime&&mtime&&ctime区别
- axel---下载工具
axel是Linux下一个不错的HTTP/ftp高速下载工具.支持多线程下载.断点续传,且可以从多个地址或者从一个地址的多个连接来下载同一个文件.适合网速不给力时多线程下载提高下载速度.比如在国内VP ...
- C# Unable to load DLL 'WzCanDll.dll':找不到指定的模块
一.打开app无法加载DLL 我用C++编写的DLL,然后用C#写的界面APP,在自己的电脑上打开没有问题,放在其它电脑上就出现无法加载DLL库的问题,一连接APP就会出现问题,如下图所示: 二.解决 ...
- dump var_dump print print_r的区别
dump var_dump print print_r的区别 一.总结 用dump()来打印就对了 1.echo和print:不能打印复合型和资源型数据: 2.var_dump()和print_r() ...