• ILGenerator.Emit动态 MSIL编程(三)之动态代理


      using System;
        using System.Linq;
        using System.Reflection;
        using System.Reflection.Emit;
    
        public sealed class DynamicProxy
        {
            private static readonly string AssemblyName = "DynamicProxy", 
                                           ModuleName = "DynamicProxy", 
                                           TypeName = "DynamicProxy";
            private AssemblyBuilder CreateDynamicAssembly<T>() where T : class
            {
                return AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(AssemblyName + typeof(T).Name),
                    AssemblyBuilderAccess.Run);
            }
            private ModuleBuilder CreateDynamicModule<T>() where T : class
            {
                return CreateDynamicAssembly<T>().DefineDynamicModule(ModuleName + typeof(T).Name);
            }
            /// <summary>
            /// 创建动态代理
            /// </summary>
            public T CreateDynamicType<T>() where T : class,new()
            {
                TypeBuilder typeBuilder = CreateDynamicModule<T>().DefineType(TypeName + typeof(T).Name, TypeAttributes.Public | 
                    TypeAttributes.Class, typeof(T));
                TypeActuator<T>(typeBuilder);
                return Activator.CreateInstance(typeBuilder.CreateType()) as T;
            }
            private void BuildCtorMethod(Type classType, FieldBuilder fieldBuilder, TypeBuilder typeBuilder)
            {
                var structureBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard,null);
                var ilCtor = structureBuilder.GetILGenerator();
                ilCtor.Emit(OpCodes.Ldarg_0);
                ilCtor.Emit(OpCodes.Newobj, classType.GetConstructor(Type.EmptyTypes));
                ilCtor.Emit(OpCodes.Stfld, fieldBuilder);
                ilCtor.Emit(OpCodes.Ret);
            }
            private void BuildMethod(ILGenerator il, MethodInfo methodInfo, Type[] ParameterTypes)
            {
                il.Emit(OpCodes.Ldarg_0);
                for (int i = 0; i < ParameterTypes.Length; i++)
                    il.Emit(OpCodes.Ldarg_S, (short)(i + 1));
                il.Emit(OpCodes.Call, methodInfo);
                il.Emit(OpCodes.Ret);
            }
            private void TypeActuator<T>(TypeBuilder builder) where T : class
            {
                FieldBuilder fieldBuilder = builder.DefineField("_DynamicProxyActuator", typeof(T), FieldAttributes.Private);
                BuildCtorMethod(typeof(T), fieldBuilder, builder);
                MethodInfo[] info = GetMethodInfo(typeof(T));
                foreach (MethodInfo methodInfo in info)
                {
                    if (!methodInfo.IsVirtual && !methodInfo.IsAbstract) continue;
                    if (methodInfo.Name == "ToString") continue;
                    if (methodInfo.Name == "GetHashCode") continue;
                    if (methodInfo.Name == "Equals") continue;
                    var ParameterTypes = methodInfo.GetParameters().Select(p => p.ParameterType).ToArray();
                    MethodBuilder methodBuilder = CreateMethod(builder, methodInfo.Name, MethodAttributes.Public | MethodAttributes.Virtual,
                        CallingConventions.Standard, methodInfo.ReturnType, ParameterTypes);
                    var ilMethod = methodBuilder.GetILGenerator();
                    BuildMethod(ilMethod, methodInfo, ParameterTypes);
                }
            }
            private MethodBuilder CreateMethod(TypeBuilder typeBuilder, string name, MethodAttributes attrs, CallingConventions callingConventions, 
                Type type, Type[] parameterTypes)
            {
                return typeBuilder.DefineMethod(name, attrs, callingConventions, type, parameterTypes);
            }
            private MethodInfo[] GetMethodInfo(Type type)
            {
                return type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
            }
        }
  • 相关阅读:
    所写既所思
    OO总结
    OO第三单元作业总结
    OO第二单元作业总结
    OO第一单元作业总结
    oo第四单元与课程总结
    oo第三单元总结——jml
    oo第二单元博客总结
    面向对象设计与构造-第一单元作业总结
    个人总结-不说再见
  • 原文地址:https://www.cnblogs.com/yuming1983/p/3809240.html
Copyright © 2020-2023  润新知