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)推出有一段时间了,最近花了点时间将它升级 ...
随机推荐
- 【SpringBoot】转载 springboot使用thymeleaf完成数据的页面展示
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/weixin_36380516/artic ...
- Vue中可用的判断对象是否为空的方法
vue有两个方法可用 1. JSON.stringify(evtValue)=='{}' 2. Object.keys(xxx).length==0 js判断对象是否为空对象的几种方法 1.将json ...
- SQL-W3School-基础:SQL AND & OR 运算符
ylbtech-SQL-W3School-基础:SQL AND & OR 运算符 1.返回顶部 1. AND 和 OR 运算符用于基于一个以上的条件对记录进行过滤. AND 和 OR 运算符 ...
- python爬虫简单实现,并在java中调用python脚本,将数据保存在json文件中
# coding:utf-8 import urllib2 from bs4 import BeautifulSoup import json import sys reload(sys) sys.s ...
- [Scikit-learn] 2.3 Clustering - Spectral clustering
From: 2.3.5 Clustering - Spectral clustering From: 漫谈 Clustering (4): Spectral Clustering From: 漫谈 C ...
- [C++]数据结构:线性表之顺序表
1 顺序表 ADT + Status InitList(SeqList &L) 初始化顺序表 + void printList(SeqList L) 遍历顺序表 + int ListLengt ...
- web框架初阶
第一站 文件结构:web--- |--home.py #页面处理函数 |--index.py #主体函数 |--indexPlus.py #主体函数加强版 |--webdaem.py #通过we ...
- docker attach 和 exec 用法区别
attach 用法 $ sudo docker attach 665b4a1e17b6 #by IDor$ sudo docker attach loving_heisenberg #by Name$ ...
- ffmpeg 使用 gdb 调试相关技巧
本文说明了,在ffmpeg二次开发或调用库的过程,如何借助于ffmpeg源码进行调试. 注:ffmpeg版本是4.0. 1. 编写代码 编写将pcm数据转换为mp2的代码 pcm_to_mp2.c # ...
- DOTS原则和愿景
Unity Data Oriented Tech Stack基于一系列原则.这些原则为我们正在努力实现的目标提供了良好的背景.一些原则清楚地反映在代码中.其他则只是我们为自己设定的目标. 默认情况下的 ...