AssemblyBuilder以及Activator双剑合璧
AssemblyBuilder和Activator两个类是DispatchProxy类实现动态代理以及AOP的根本,示例demo可参考 DispatchProxy实现动态代理及AOP 。AssemblyBuilder的命名空间是System.Reflection.Emit,没错就是你听过的Emit。那么它是干什么用的?先看看 官方 的示例代码:
// ↓ AssemblyBuilder构造自定义类
AssemblyName aName = new AssemblyName("DynamicAssemblyExample");
AssemblyBuilder ab =
AssemblyBuilder.DefineDynamicAssembly(
aName,
AssemblyBuilderAccess.Run);
ModuleBuilder mb =
ab.DefineDynamicModule(aName.Name);
TypeBuilder tb = mb.DefineType(
"MyDynamicType",
TypeAttributes.Public);
FieldBuilder fbNumber = tb.DefineField(
"m_number",
typeof(int),
FieldAttributes.Private);
Type[] parameterTypes = { typeof(int) };
ConstructorBuilder ctor1 = tb.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
parameterTypes);
ILGenerator ctor1IL = ctor1.GetILGenerator();
ctor1IL.Emit(OpCodes.Ldarg_0);
ctor1IL.Emit(OpCodes.Call,
typeof(object).GetConstructor(Type.EmptyTypes));
ctor1IL.Emit(OpCodes.Ldarg_0);
ctor1IL.Emit(OpCodes.Ldarg_1);
ctor1IL.Emit(OpCodes.Stfld, fbNumber);
ctor1IL.Emit(OpCodes.Ret);
ConstructorBuilder ctor0 = tb.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes);
ILGenerator ctor0IL = ctor0.GetILGenerator();
ctor0IL.Emit(OpCodes.Ldarg_0);
ctor0IL.Emit(OpCodes.Ldc_I4_S, 42);
ctor0IL.Emit(OpCodes.Call, ctor1);
ctor0IL.Emit(OpCodes.Ret);
PropertyBuilder pbNumber = tb.DefineProperty(
"Number",
PropertyAttributes.HasDefault,
typeof(int),
null);
MethodAttributes getSetAttr = MethodAttributes.Public |
MethodAttributes.SpecialName | MethodAttributes.HideBySig;
MethodBuilder mbNumberGetAccessor = tb.DefineMethod(
"get_Number",
getSetAttr,
typeof(int),
Type.EmptyTypes);
ILGenerator numberGetIL = mbNumberGetAccessor.GetILGenerator();
numberGetIL.Emit(OpCodes.Ldarg_0);
numberGetIL.Emit(OpCodes.Ldfld, fbNumber);
numberGetIL.Emit(OpCodes.Ret);
MethodBuilder mbNumberSetAccessor = tb.DefineMethod(
"set_Number",
getSetAttr,
null,
new Type[] { typeof(int) });
ILGenerator numberSetIL = mbNumberSetAccessor.GetILGenerator();
numberSetIL.Emit(OpCodes.Ldarg_0);
numberSetIL.Emit(OpCodes.Ldarg_1);
numberSetIL.Emit(OpCodes.Stfld, fbNumber);
numberSetIL.Emit(OpCodes.Ret);
pbNumber.SetGetMethod(mbNumberGetAccessor);
pbNumber.SetSetMethod(mbNumberSetAccessor);
MethodBuilder meth = tb.DefineMethod(
"MyMethod",
MethodAttributes.Public,
typeof(int),
new Type[] { typeof(int) });
ILGenerator methIL = meth.GetILGenerator();
methIL.Emit(OpCodes.Ldarg_0);
methIL.Emit(OpCodes.Ldfld, fbNumber);
methIL.Emit(OpCodes.Ldarg_1);
methIL.Emit(OpCodes.Mul);
methIL.Emit(OpCodes.Ret);
Type t = tb.CreateType();
//↑ AssemblyBuilder类代码
MethodInfo mi = t.GetMethod("MyMethod");
PropertyInfo pi = t.GetProperty("Number");
//↓ Activator调用自定义的类
object o1 = Activator.CreateInstance(t);
Console.WriteLine("o1.Number: {0}", pi.GetValue(o1, null));
pi.SetValue(o1, 127, null);
Console.WriteLine("o1.Number: {0}", pi.GetValue(o1, null));
object[] arguments = { 22 };
Console.WriteLine("o1.MyMethod(22): {0}",
mi.Invoke(o1, arguments));
object o2 = Activator.CreateInstance(t,
new object[] { 5280 });
Console.WriteLine("o2.Number: {0}", pi.GetValue(o2, null));
// ↑Activator 类代码
Console.Read();
先看看输出结果吧:

我猜您看的迷糊吧,这都啥玩意,不急。对AssemblyBuilder以及Activator的概念是:动态创建类型。上面的代码中的AssemblyBuilder相关代码是动态的构造一个完整的类型,包括了类的行为(方法)、状态(字段、属性),构造函数等。相当于就是一个类型的定义:
public class MyDynamicType
{
private int m_number;
public MyDynamicType() : this(42) {}
public MyDynamicType(int initNumber)
{
m_number = initNumber;
}
public int Number
{
get { return m_number; }
set { m_number = value; }
}
public int MyMethod(int multiplier)
{
return m_number * multiplier;
}
}
这就是AssemblyBuilder类的作用了,那么Activator类的作用呢?其实你也应该猜到了,就是一个实例化类型及调用对象的过程。
AssemblyBuidler类 + Activator类 两者的结合可以实现动态代理以及AOP,功能及其强大,园子里蒋老大的Dora AOP框架的代码中也有这两个类。
AssemblyBuilder以及Activator双剑合璧的更多相关文章
- MarkDown、Vim双剑合璧
作为一名软件攻城狮(是的,我从来都以攻城狮自居! 我坚信如今的每一天,都在朝攻城狮迈进.虽然被菜鸟的肉身皮囊裹着,我依然还是怀着攻城狮的内心! 我非常讨厌别人喊我程序猿.虽然这是不争的事实!).... ...
- Spring Cloud & Alibaba 实战 | 第十二篇: 微服务整合Sentinel的流控、熔断降级,赋能拥有降级功能的Feign新技能熔断,实现熔断降级双剑合璧(JMeter模拟测试)
目录 一. Sentinel概念 1. 什么是Sentinel? 2. Sentinel功能特性 3. Sentinel VS Hystrix 二. Docker部署Sentinel Dashboar ...
- ViewBinding 与 Kotlin 委托双剑合璧
请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · Android-NoteBook 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭 ...
- [转帖]双剑合璧:CPU+GPU异构计算完全解析
引用自:http://tech.sina.com.cn/mobile/n/2011-06-20/18371792199.shtml 这篇文章写的深入浅出,把异构计算的思想和行业趋势描述的非常清楚,难得 ...
- ASP.NET Core和Angular 2双剑合璧
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:两个还没有正式发布的东西一起用,是什么效果? 效果当然会很好了(我猜的),那么如何在A ...
- JUnit4 与 JMock 之双剑合璧
引言 单元测试可以保证代码的质量,最大程度降低修复系统 bug 的时间和成本.能被称为测试的阶段有:单元测试.集成测试.系统测试和用户测试.修复系统 bug 的时间和成本随着这些阶段的推移呈指数级增长 ...
- Go+Python双剑合璧
目的 Python调用Go的方法,Python有很多功能强悍又使用简洁的库.而新生军Go的多核心利用率也是非常强悍的.当然这是明面上的优点.反正你有很多理由想要让Python能够调用Go的方法. 实验 ...
- 双剑合璧——掌握 cURL 和 Dig 走天涯
如今随着大量的应用转移到网络,作为开发者,会经常做一些通讯测试,例如从网站获取信息.模拟用户向网站提交或者上传数据,查看应用通讯情况等等,现在变成了非常重要的任务. 一起来认识 cURL cURL 是 ...
- 双剑合璧的开源项目Kitty-Cloud
项目地址 https://github.com/yinjihuan/kitty-cloud 背景 做这个项目主要是想将个人的一些经验通过开源的形式进行输出,不一定能帮到所有人,有感兴趣的朋友可以关注学 ...
随机推荐
- JS的静态类型检测,有内味儿了
我们知道 TypeScript 2.3 以后的版本支持使用--checkJs对.js文件进行类型检查和错误提示. 但是由于 JavaScript 是弱类型语言,在编写代码的时候,是无法检测变量的类型的 ...
- 前端跨域 nginx 反向代理
1.下载ngnix稳定版 (http://nginx.org/en/download.html) 2.解压到你中意的目录. 3.将你的网页文件放到刚解压html文件目录下 4.打开conf &g ...
- Pandas学习(三)——NBA球员薪资分析
欢迎加入python学习交流群 667279387 学习笔记汇总 Pandas学习(一)–数据的导入 pandas学习(二)–双色球数据分析 pandas学习(三)–NAB球员薪资分析 pandas学 ...
- [TimLinux] WireShark 安装篇——CentOS7
1. 下载 libpcap: http://www.tcpdump.org/release/libpcap-1.9.0.tar.gz cmake: https://github-production- ...
- HDU3710 Battle over Cities(最小生成树+树链剖分+倍增+线段树)
Battle over Cities Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- A*算法在最短路问题的应用及其使用举例
1 A*算法 A*算法在人工智能中是一种典型的启发式搜索算法,启发中的估价是用估价函数表示的: 其中f(n)是节点n的估价函数,g(n)表示实际状态空间中从初始节点到n节点的实际代价,h(n)是从n到 ...
- 最全的linux基础命令
第1章 linux命令 1.1 线上查询及帮助命令 help命令*** help前面接你要查询的命令:例如ls [root@server02 ~]# ls --help 用法:ls [选项]... [ ...
- 使用chole创建一个连接池
using Chloe; using Chloe.Infrastructure; using Chloe.SqlServer; using System; using System.Collectio ...
- [问题记录]——log4net记录多个级别文件
目录 前言 Log4net 测试 小结 前言 不知不觉可都快又一年了,最近这段时间一直在忙着图形方面的东西(确实快给我搞死了),虽说时间还是相对有的,但是精力耗费的十有十一,把问题记录单开一栏,是为了 ...
- 5G 调制与解调
调制,就是将原始信号转换为适合在信道中传输的形式的一种过程,在无线通信中,调制一般均指载波调制,而解调则是调制的逆过程,即将原始信号从已调信号中恢复出来. 进行载波调制,主要为实现以下目标: 1)在无 ...