• 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框架的代码中也有这两个类。

  • 相关阅读:
    java基础3 循环语句:While 循环语句、do while 循环语句、 for 循环语句 和 break、continue关键字
    java基础2 判断语句:if ... else 语句和 switch 语句
    IT行业经典面试技巧及方法思路。
    Java基础1,入门基础知识
    SVN的使用、分支合并及解决冲突详解
    VC工程产生文件后缀名解释
    ireport报表,打印时,报表加载失败的解决方法
    MySQL 事务、视图、索引
    MySQL高级查询
    MySQL中的主键约束和外键约束
  • 原文地址:https://www.cnblogs.com/zhiyong-ITNote/p/11060261.html
Copyright © 2020-2023  润新知