代码改变世界

动态代理 2

2020-11-24 11:28  qgbo  阅读(109)  评论(0编辑  收藏  举报

下面代码,可以是基于上一篇的源码,精简出来的。方便理解

public class MTest
    {
        public MTest()
        {
            Console.WriteLine("MTest");
        }
        public string Tt()
        {
            Console.WriteLine("tt");
            return "123";
        }
    }
    class Program
    {

        static void A()
        {
            Console.WriteLine("AAAAA");
        }


        static void Main(string[] argsm)
        {
            var baseType = typeof(MTest);
            TypeInfo baseTypeInfo = baseType.GetTypeInfo();

            var _tb = AssemblyBuilder
                .DefineDynamicAssembly(new AssemblyName("ProxyBuilder"), AssemblyBuilderAccess.RunAndCollect)
                .DefineDynamicModule("testmod")
                .DefineType("name_nextId", TypeAttributes.Public, baseTypeInfo);

            var _fields = new List<FieldBuilder>();
            //_fields.Add(_tb.DefineField("invoke", typeof(Action<object[]>), FieldAttributes.Private));

            var args=_fields.Select(t => t.FieldType).ToArray();
            

            var  cb = _tb.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, args);


            // chained ctor call
            var baseCtor = baseTypeInfo
                .DeclaredConstructors
                .SingleOrDefault(c => c.IsPublic && c.GetParameters().Length == 0);

            ILGenerator il = cb.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, baseCtor!);

            //// store all the fields
            for (int i = 0; i < args.Length; i++)
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldarg, i + 1);
                il.Emit(OpCodes.Stfld, _fields[i]);
            }

            il.Emit(OpCodes.Ret);

            var type=_tb.CreateTypeInfo()!.AsType();
        
            var a=Activator.CreateInstance(type) as MTest;


            Console.WriteLine("Hello World!");

            var mockMessaging = new MoqTest<IMessaging>(A);
            mockMessaging.Object.SendTo();
            Console.WriteLine("start..");
            return;
        }
    }