zoukankan      html  css  js  c++  java
  • 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);
            }
        }
  • 相关阅读:
    使用 Spring data redis 结合 Spring cache 缓存数据配置
    Spring Web Flow 笔记
    Linux 定时实行一次任务命令
    css js 优化工具
    arch Failed to load module "intel"
    go 冒泡排序
    go (break goto continue)
    VirtualBox,Kernel driver not installed (rc=-1908)
    go运算符
    go iota
  • 原文地址:https://www.cnblogs.com/yuming1983/p/3809240.html
Copyright © 2011-2022 走看看