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双剑合璧的更多相关文章

  1. MarkDown、Vim双剑合璧

    作为一名软件攻城狮(是的,我从来都以攻城狮自居! 我坚信如今的每一天,都在朝攻城狮迈进.虽然被菜鸟的肉身皮囊裹着,我依然还是怀着攻城狮的内心! 我非常讨厌别人喊我程序猿.虽然这是不争的事实!).... ...

  2. Spring Cloud & Alibaba 实战 | 第十二篇: 微服务整合Sentinel的流控、熔断降级,赋能拥有降级功能的Feign新技能熔断,实现熔断降级双剑合璧(JMeter模拟测试)

    目录 一. Sentinel概念 1. 什么是Sentinel? 2. Sentinel功能特性 3. Sentinel VS Hystrix 二. Docker部署Sentinel Dashboar ...

  3. ViewBinding 与 Kotlin 委托双剑合璧

    请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · Android-NoteBook 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭 ...

  4. [转帖]双剑合璧:CPU+GPU异构计算完全解析

    引用自:http://tech.sina.com.cn/mobile/n/2011-06-20/18371792199.shtml 这篇文章写的深入浅出,把异构计算的思想和行业趋势描述的非常清楚,难得 ...

  5. ASP.NET Core和Angular 2双剑合璧

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:两个还没有正式发布的东西一起用,是什么效果? 效果当然会很好了(我猜的),那么如何在A ...

  6. JUnit4 与 JMock 之双剑合璧

    引言 单元测试可以保证代码的质量,最大程度降低修复系统 bug 的时间和成本.能被称为测试的阶段有:单元测试.集成测试.系统测试和用户测试.修复系统 bug 的时间和成本随着这些阶段的推移呈指数级增长 ...

  7. Go+Python双剑合璧

    目的 Python调用Go的方法,Python有很多功能强悍又使用简洁的库.而新生军Go的多核心利用率也是非常强悍的.当然这是明面上的优点.反正你有很多理由想要让Python能够调用Go的方法. 实验 ...

  8. 双剑合璧——掌握 cURL 和 Dig 走天涯

    如今随着大量的应用转移到网络,作为开发者,会经常做一些通讯测试,例如从网站获取信息.模拟用户向网站提交或者上传数据,查看应用通讯情况等等,现在变成了非常重要的任务. 一起来认识 cURL cURL 是 ...

  9. 双剑合璧的开源项目Kitty-Cloud

    项目地址 https://github.com/yinjihuan/kitty-cloud 背景 做这个项目主要是想将个人的一些经验通过开源的形式进行输出,不一定能帮到所有人,有感兴趣的朋友可以关注学 ...

随机推荐

  1. Linux系统通过FTP进行文档基本操作【华为云分享】

    [摘要] Linux系统里通过FTP可以对文档进行上传,更改权限和基本的文档管理. 获得Linux系统后,不熟悉命令操作的情况下,可以通过FTP工具进行文档操作,下面以WinSCP工具为例进行讲解: ...

  2. Python开发GUI工具介绍,实战:将图片转化为素描画!

    欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...

  3. 关于TC297的Flash写入之前是否需要先擦除的问题

    通过实际测试,对TC297 Flash的一个地址空间可以重复执行写入操作(program),而不需要先对该区域所在扇区进行擦除. MPC5675K则需要在写入之前进行擦除.

  4. Dict.setdefault()

    """ setdefault方法参数输入已有键,返回对应值,找不到已有键,创建新键,值为None """ >>> dict ...

  5. springboot整合activiti

    1.第一步添加bpmn文件得插件,不然没法查看和编辑bpmn文件,添加插件的方法各自百度即可,很简单 2.安装好bpmn插件后开始新建bpmn文件,也就是画流程图 一般是在代码中进行指定流程审批人的, ...

  6. 侠梦说pinpoint--界面上的图标之AgetnInfo数据研究

    前言 在启动一个挂载pinpoint的springboot项目的时候,界面上显示成了jboss的图标,所以今天研究了一下这个数据是怎么来的. 我们知道不同图标和服务类型有关,服务不同,图标就不同,这在 ...

  7. 有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务

    更多云原生技术资讯可关注阿里巴巴云原生技术圈. Puppeteer 是什么? puppeteer 官网的介绍如下: Puppeteer is a Node library which provides ...

  8. Servlet和Tomcat底层源码分析

    Servlet 源码分析   Servlet 结构图 Servlet 和 ServletConfig 都是顶层接口,而 GenericServlet 实现了这两个顶层接口,然后HttpServlet ...

  9. ARTS-S k8s常用命令

    本地访问minikube的docker eval $(minikube docker-env) 删除statefulset kubectl delete statefulset web --casca ...

  10. 记录XunSearch(讯搜)的使用教程步骤(CentOS7下)

    一.安装编译工具 yum install make gcc g++ gcc-c++ libtool autoconf automake imake mysql-devel libxml2-devel ...