zoukankan      html  css  js  c++  java
  • 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框架的代码中也有这两个类。

  • 相关阅读:
    x+=y与x=x+y有什么区别?
    Linux下带宽流量工具iftop实践
    使用pinyin4j实现汉字转拼音
    Spring整合Velocity模版引擎
    Json工具类库之Gson实战笔记
    腾讯移动分析 签名代码示例
    Docker搭建Portainer可视化界面
    maven 打包 spring boot 生成docker 镜像
    Mysql 为什么要选择 B+Tree
    idea 添加 注释 配置
  • 原文地址:https://www.cnblogs.com/zhiyong-ITNote/p/11060261.html
Copyright © 2011-2022 走看看