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); } }