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)推出有一段时间了,最近花了点时间将它升级 ...
随机推荐
- 我用asp.net core 部署到docker遇到的问题
1.怎么部署 我是用文件的形式先发布出来,然后把文件拷贝到服务器上部署到docker中去. 2.端口映射 根据查找到的资料,dockerfile 是不支持指定映射服务器端口的,只能在run的时候用-p ...
- Django中的 返回json对象的方式
在返回json对象的几种方式: 1 from django.shortcuts import render, HttpResponse # Create your views here. from d ...
- 北大ACM - POJ试题分类
1.入门水题 可用于练手与增强自信 POJ-1003POJ-1004 POJ-1005 POJ-1207 POJ-3299 POJ-2159 POJ-1083POJ-3094 2.初级 2.1. 基本 ...
- SQL-W3School-高级:SQL DEFAULT 约束
ylbtech-SQL-W3School-高级:SQL DEFAULT 约束 1.返回顶部 1. SQL DEFAULT 约束 DEFAULT 约束用于向列中插入默认值. 如果没有规定其他的值,那么会 ...
- springboot之rabbitmq安装与实践
环境:腾讯云centos7 注意:rabbitmq安装插件,可能会报错.本人是主机名的问题,所以修改了主机名. vim /etc/hosts vim /etc/hostname 修改这两个文件,并重启 ...
- sql控制流if()、case when then
tb_user: 1.if (expr1,expr2,expr3) #如果expr1成立,则返回expr2,否则返回expr3示例:select name, if (sex=1,'男','女') ...
- 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_22-CMS前端页面查询开发-Api调用-跨域解决
点击页面查询按钮 ,报错.跨域问题. 前端端口是11000 请求后端的服务地址端口是31001 出现跨域 开始解决跨域 把前面带端口的地址 用变量代替 只有带/api/cms开头的就转发的服务端310 ...
- iOS-自定义导航控制器
BasicNavigationViewController:UINavigationViwController /* 隐藏导航底部线条 */ -(void)viewDidLoad{ [super ...
- unity 读取灰度图生成按高程分层设色地形模型
准备灰度图 1.高程按比例对应hue色相(hsv)生成mesh效果 o.color = float4(hsv2rgb(float3(v.vertex.y/100.0, 0.5, 0.75)), 1.0 ...
- 【ABAP系列】SAP ABAP下载带密码的Excel文件
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP下载带密码的Ex ...