C# 使用Emit实现动态AOP框架 (一)
目 录
最近需要有一个完全自主的基于C#语言的Aop框架,查了一下资料实现方式主要分为:静态织入和动态代理,静态织入以Postshop为代表,而动态代理又分为:
1、普通反射
2、Emit反射
3、微软提供的.Net Remoting和RealProxy
(微软官方例子https://msdn.microsoft.com/zh-cn/library/dn574804.aspx)
总体来说静态织入速度最快,普通反射最慢,而.Net Remoting和RealProx实现起来又相对较复杂。而Emit速度居中,同时其一次生成后,将结果序列化,速度也并不慢,同时和原有类并没有紧密耦合,通过外部配置文件可以方便的控制要进行代理的类型、方法和属性,其缺点是被代理的方法、属性必须为virtual类型。
一、被代理类和代理类
被代理类,是我们正常使用的类,里边是原有的业务逻辑,只要在被代理方法上申明上相应的切面特性就行了,使用起来比较简单;如下
public class AopTest
{ public AopTest()
{
Name = "小明"; Age = ;
} public AopTest(string name, int age)
{
Name = name; Age = age;
} [Log]
public virtual string Name { get; set; } [Log]
public virtual int Age { get; set; } [Log]
public virtual int NYearLater(int a)
{
int larter = Age + a; return larter;
}
}
代理类是Aop框架自动生成的类,使用反编译工具我们可以看到,它比被代理类多了切面上下文声明(AspectContent)和相应的切面特性对象声明,在被代理类的方法执行前后,相应切面特性调用OnEntry、OnExit执行相关操作,如日志、参数验证、权限验证等等Aop功能,其中AspectContext是OnEntry、OnExit调用参数,如下:
public class AopTest_Proxy : AopTest
{
public override string Name
{
get
{
object[] args = new object[];
AspectContext aspectContext = new AspectContext(this, "get_Name", args);
LogAttribute logAttribute = new LogAttribute();
logAttribute.OnEntry(aspectContext);
string name = base.Name;
aspectContext.Result = name;
logAttribute.OnExit(aspectContext);
return name;
}
set
{
AspectContext context = new AspectContext(this, "set_Name", new object[]
{
value
});
LogAttribute logAttribute = new LogAttribute();
logAttribute.OnEntry(context);
base.Name = value;
logAttribute.OnExit(context);
}
} public override int Age
{
get
{
object[] args = new object[];
AspectContext aspectContext = new AspectContext(this, "get_Age", args);
LogAttribute logAttribute = new LogAttribute();
logAttribute.OnEntry(aspectContext);
int age = base.Age;
aspectContext.Result = age;
logAttribute.OnExit(aspectContext);
return age;
}
set
{
AspectContext context = new AspectContext(this, "set_Age", new object[]
{
value
});
LogAttribute logAttribute = new LogAttribute();
logAttribute.OnEntry(context);
base.Age = value;
logAttribute.OnExit(context);
}
} public AopTest_Proxy(string name, int age) : base(name, age)
{
} public override int NYearLater(int num)
{
AspectContext aspectContext = new AspectContext(this, "NYearLater", new object[]
{
num
});
LogAttribute logAttribute = new LogAttribute();
logAttribute.OnEntry(aspectContext);
int num2 = base.NYearLater(num);
aspectContext.Result = num2;
logAttribute.OnExit(aspectContext);
return num2;
}
}
二、测试方法
public static void Test()
{
try
{
AopTest WithPara = DynamicProxy.Create<AopTest>("lxl", ); ; WithPara.NYearLater();
Console.WriteLine("done...");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
测试方法中:AopTest WithPara = DynamicProxy.Create<AopTest>("lxl", 10); ,生成一个代理对象,其他就正常使用就可以了。
调用测试方法执行结果如下:
Log OnEntry:set_Name(lxl)
Log OnExit: set_Name Log OnEntry:set_Age()
Log OnExit: set_Age Log OnEntry:NYearLater()
Log OnEntry:get_Age()
Log OnExit: get_Age Result: Log OnExit: NYearLater Result: done...
通过结果可以看到 属性Name、Age的Set方法,NYearLater方法,以及Age属性的Get方法都实现了日志记录。下边将分几篇来详细介绍DynamicProxy类的实现。欢迎大家多多指正、交流。
C# 使用Emit实现动态AOP框架 (一)的更多相关文章
- C# 使用Emit实现动态AOP框架 (三)
目 录 C# 使用Emit实现动态AOP框架 (一) C# 使用Emit实现动态AOP框架 (二) C# 使用Emit实现动态AOP框架 (三) C# 使用Emit实现动态AOP框架 进阶篇之异常处 ...
- C# 使用Emit实现动态AOP框架 (二)
目 录 C# 使用Emit实现动态AOP框架 (一) C# 使用Emit实现动态AOP框架 (二) C# 使用Emit实现动态AOP框架 (三) C# 使用Emit实现动态AOP框架 进阶篇之异常处 ...
- C# 使用Emit实现动态AOP框架 进阶篇之异常处理
目 录 C# 使用Emit实现动态AOP框架 (一) C# 使用Emit实现动态AOP框架 (二) C# 使用Emit实现动态AOP框架 (三) C# 使用Emit实现动态AOP框架 进阶篇之异常处 ...
- C# 使用Emit实现动态AOP框架 进阶篇之优化
目 录 C# 使用Emit实现动态AOP框架 (一) C# 使用Emit实现动态AOP框架 (二) C# 使用Emit实现动态AOP框架 (三) C# 使用Emit实现动态AOP框架 进阶篇之异常处 ...
- C#利用Emit反射实现AOP,以及平台化框架封装思路
C#利用Emit反射实现AOP,以及平台化框架封装思路 这是前两天扒的一段动态代理AOP代码,用的Emit反射生成子类来实现代理模式,在这里做个小笔记,然后讨论一下AOP框架的实现思路. 首先是主函数 ...
- .NET 下基于动态代理的 AOP 框架实现揭秘
.NET 下基于动态代理的 AOP 框架实现揭秘 Intro 之前基于 Roslyn 实现了一个简单的条件解析引擎,想了解的可以看这篇文章 https://www.cnblogs.com/weihan ...
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...
- JAVA基础加强(张孝祥)_类加载器、分析代理类的作用与原理及AOP概念、分析JVM动态生成的类、实现类似Spring的可配置的AOP框架
1.类加载器 ·简要介绍什么是类加载器,和类加载器的作用 ·Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader ...
- Dora.Interception,为.NET Core度身打造的AOP框架:全新的版本
Dora.Interception 1.0(Github地址:可以访问GitHub地址:https://github.com/jiangjinnan/Dora)推出有一段时间了,最近花了点时间将它升级 ...
随机推荐
- 如何把Java的double类型变量保留两位小数
已知 双精度标量 f, 如果想以字符串形式输出,小数点后保留2位,可直接通过C语言的输出格式,System.out.printf("%.2f", f), 达到目的. 如果想要先转 ...
- <frameset>和<body>不能共用
frameset 定义: frameset 元素可定义一个框架集.它被用来组织多个窗口(框架).每个框架存有独立的文档.在其最简单的应用中,frameset 元素仅仅会规定在框架集中存在多少列或多少行 ...
- MongoDB安装成windows 服务
观看本文之间,请先移步至下面纠正部分 之前按照MongoDB官网提供的安装方法一直出错 http://cn.docs.mongodb.org/master/tutorial/install-mongo ...
- 14Flutter StatefulWidget有状态组件、页面上绑定数据、改变页面数据、实现计数器功能、动态列表
/** * Flutter StatefulWidget有状态组件.页面上绑定数据.改变页面数据 * 在Flutter中自定义组件其实就是一个类,这个类需要继承StatelessWidget/Stat ...
- 用VLC读取摄像头产生RTSP流,DSS主动取流转发(一)
用VLC读取摄像头产生RTSP流,DSS主动取流转发(一) 摄像机地址是192.1.101.51,VLC运行在192.1.101.77上,DSS服务器架设在192.1.101.30上. Step1:V ...
- CentOS7使用yum安装mysql5.7
提前说一下,网速不好不要用yum安装,等得时间太长. 第一步.获取yum源 [root@youxi1 ~]# rpm -ivh https://repo.mysql.com/yum/mysql-5.7 ...
- 分JOB实例
*&---------------------------------------------------------------------* *& Form F_SET_JOB * ...
- Unity 实现橡皮擦效果
我所实现的橡皮擦效果是设置图片某点的像素的透明度为0,来简单实现擦除效果的: 下面是效果 首先需要注意两点:1:设置 Main Camera 的 projection 属性为Orthographic ...
- Grep---linux系统三剑客(一)
grep .sed.awk被称为linux中的"三剑客". grep 更适合单纯的查找或匹配文本 sed 更适合编辑匹配到的文本 awk 更适合格式化文本,对文本进行较复杂格式 ...
- java 中 this 和 super 说明及在构造器中super()和this()相互调用执行顺序
this this 表示当前对象 使用上细分的话,this有 this. 和this()的使用情况 ,下面我们开始细撸 this . 使用场景一: 在成员方法中,this.变量名 指带当前对象的变量, ...