| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- using System;
- using System.Linq;
- using System.Reflection;
- using System.Reflection.Emit;
- namespace SHJX.Service.Common.Proxy
- {
- /// <summary>
- /// 代理类
- /// </summary>
- public static class Proxy
- {
- public static object NewProxyInstance(Type realObj, object proxyObj)
- {
- string nameOfAssembly = realObj.Name + "ProxyAssembly";
- string nameOfModule = realObj.Name + "ProxyModule";
- string nameOfType = realObj.Name + "Proxy";
- var assemblyName = new AssemblyName(nameOfAssembly);
- var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
- var moduleBuilder = assembly.DefineDynamicModule(nameOfModule);
- var typeBuilder = moduleBuilder.DefineType(nameOfType, TypeAttributes.Public | TypeAttributes.NotPublic, realObj);
- InjectInterceptor(realObj, typeBuilder, proxyObj);
- var t = typeBuilder.CreateType();
- return Activator.CreateInstance(t);
- }
- private static void InjectInterceptor(Type type, TypeBuilder typeBuilder, object proxy)
- {
- var fieldInterceptor = typeBuilder.DefineField("_interceptor", proxy.GetType(), FieldAttributes.Private);
- var constructorBuilder =
- typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null);
- var ilOfCtor = constructorBuilder.GetILGenerator();
- ilOfCtor.Emit(OpCodes.Ldarg_0);
- ilOfCtor.Emit(OpCodes.Newobj, proxy.GetType().GetConstructor(Array.Empty<Type>())!);
- ilOfCtor.Emit(OpCodes.Stfld, fieldInterceptor);
- ilOfCtor.Emit(OpCodes.Ret);
- var methodsOfType = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
- foreach (var method in methodsOfType)
- {
- var methodParameterTypes = method.GetParameters().Select(p => p.ParameterType).ToArray();
- var attr = MethodAttributes.Public | MethodAttributes.Virtual;
- var methodBuilder = typeBuilder.DefineMethod(method.Name, attr, CallingConventions.Standard,
- method.ReturnType, methodParameterTypes);
- var ilOfMethod = methodBuilder.GetILGenerator();
- ilOfMethod.Emit(OpCodes.Ldarg_0);
- ilOfMethod.Emit(OpCodes.Ldfld, fieldInterceptor);
- ilOfMethod.Emit(OpCodes.Newobj, type.GetConstructor(Array.Empty<Type>())!);
- ilOfMethod.Emit(OpCodes.Ldstr, method.Name);
- var parameters = ilOfMethod.DeclareLocal(typeof(object[]));
- ilOfMethod.Emit(OpCodes.Ldc_I4, methodParameterTypes.Length);
- ilOfMethod.Emit(OpCodes.Newarr, typeof(object));
- ilOfMethod.Emit(OpCodes.Stloc, parameters);
- for (var j = 0; j < methodParameterTypes.Length; j++)
- {
- ilOfMethod.Emit(OpCodes.Ldloc, parameters);
- ilOfMethod.Emit(OpCodes.Ldc_I4, j);
- ilOfMethod.Emit(OpCodes.Ldarg, j + 1);
- ilOfMethod.Emit(OpCodes.Stelem_Ref);
- }
- ilOfMethod.Emit(OpCodes.Ldloc, parameters);
- ilOfMethod.Emit(OpCodes.Callvirt, proxy.GetType().GetMethod("Invoke")!);
- if (method.ReturnType == typeof(void))
- {
- ilOfMethod.Emit(OpCodes.Pop);
- }
- ilOfMethod.Emit(OpCodes.Ret);
- }
- }
- }
- }
|