public void Generate(GeneratorTypeContext context) { var classType = context.ClassType; if (context.InterfaceType == null) { var typeBuilder = context.ModuleBuilder.DefineType( $"{classType.Name}_AspectFlare", classType.Attributes ); typeBuilder.SetParent(classType); context.TypeBuilder = typeBuilder; } else { context.TypeBuilder = context.ModuleBuilder.DefineType( $"<AspectFlare>{classType.Name}", classType.Attributes, typeof(object), new Type[] { context.InterfaceType } ); } if (classType.IsGenericTypeDefinition) { GenerateGeneric(classType, context.TypeBuilder); } }
public void GenerateInit(GeneratorTypeContext context) { var initBuilder = context.TypeBuilder.DefineMethod( "<Proxy>__init", MethodAttributes.Private | MethodAttributes.HideBySig, CallingConventions.HasThis ); var initGenerator = initBuilder.GetILGenerator(); var typeLocal = initGenerator.DeclareLocal(typeof(Type)); var hasInterface = context.InterfaceType != null; initGenerator.Emit(OpCodes.Ldarg_0); if (hasInterface) { initGenerator.Emit(OpCodes.Ldtoken, context.InterfaceType); initGenerator.Emit(OpCodes.Call, ReflectionInfoProvider.GetTypeFromHandle); } initGenerator.Emit(OpCodes.Ldtoken, context.ClassType); initGenerator.Emit(OpCodes.Call, ReflectionInfoProvider.GetTypeFromHandle); initGenerator.Emit(OpCodes.Ldtoken, context.TypeBuilder); initGenerator.Emit(OpCodes.Call, ReflectionInfoProvider.GetTypeFromHandle); initGenerator.Emit(OpCodes.Newobj, hasInterface ? ReflectionInfoProvider.InterceptorWrapperCollectionByInterface : ReflectionInfoProvider.InterceptorWrapperCollectionByClass ); initGenerator.Emit(OpCodes.Stfld, context.Wrappers); initGenerator.Emit(OpCodes.Ret); context.InitMethod = initBuilder; }
public GeneratorContext(GeneratorTypeContext context) { this.TypeBuilder = context.TypeBuilder; this.Wrappers = context.Wrappers; this.ClassType = context.ClassType; this.InterfaceType = context.InterfaceType; this.Interface = context.Interface; this.InitMethod = context.InitMethod; this.Token = context.Token++; }
public override void Generate(GeneratorTypeContext context) { if (context.InterfaceType != null) { GenerateInterface(context); } else { GenerateClass(context); } }
private void GenerateClass(GeneratorTypeContext context) { var classType = context.ClassType; var typeBuilder = context.TypeBuilder; bool hasClassIntercept = classType.HasInterceptAttribute(); foreach (var proxyMethod in classType.GetMethods( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ).Where( x => x.IsVirtual && (x.IsPublic || x.IsFamily) )) { if (proxyMethod.IsDefined(typeof(NonInterceptAttribute))) { continue; } if (!proxyMethod.HasDefineInterceptAttribute() && !hasClassIntercept) { continue; } if (proxyMethod.ReturnType.IsByRef) { continue; } context.MethodHandles.Add(proxyMethod.MethodHandle); var baseParameterInfos = proxyMethod.GetParameters(); // 定义方法 MethodBuilder methodBuilder = typeBuilder.DefineMethod( proxyMethod.Name, proxyMethod.Attributes ^ MethodAttributes.NewSlot, CallingConventions.HasThis | CallingConventions.Standard, proxyMethod.ReturnType, baseParameterInfos.Select(x => x.ParameterType).ToArray() ); methodBuilder.SetReturnType(proxyMethod.ReturnType); methodBuilder.SetMethodParameters(proxyMethod, baseParameterInfos); ILGenerator methodGenerator = methodBuilder.GetILGenerator(); GenerateMethod(methodBuilder, proxyMethod, null, methodGenerator, context, baseParameterInfos); typeBuilder.DefineMethodOverride(methodBuilder, proxyMethod); } }
public void Generate(GeneratorTypeContext context) { context.Wrappers = context.TypeBuilder.DefineField( "<_wrappers>", typeof(InterceptorWrapperCollection), FieldAttributes.Private ); if (context.InterfaceType != null) { context.Interface = context.TypeBuilder.DefineField( $"<{context.ClassType.Name}>_i", context.InterfaceType, FieldAttributes.Private ); } }
protected void GenerateMethod( MethodBase methodBuilder, MethodBase classMethod, MethodInfo interfaceMethod, ILGenerator generator, GeneratorTypeContext typeContext, ParameterInfo[] parameters ) { var context = GetMethodContext( methodBuilder, classMethod, interfaceMethod, generator, typeContext, parameters ); GenerateDynamicMethod(context); }
private Type GenerateProxyType(Type interfaceType, Type classType) { var context = new GeneratorTypeContext { ModuleBuilder = _moduleBuilder, ClassType = classType, InterfaceType = interfaceType }; DefineTypeOperator.Generate(context); DefineFieldsOperator.Generate(context); ImplementConstructorsOperator.Generate(context); ImplementMethodsOperator.Generate(context); var proxyType = context.TypeBuilder.CreateTypeInfo(); HandleCollection.AddHandles(proxyType.MetadataToken, context.MethodHandles); return(proxyType); }
private static GeneratorContext GetMethodContext( MethodBase builder, MethodBase proxyMethod, MethodInfo interfaceMethod, ILGenerator generator, GeneratorTypeContext typeContext, ParameterInfo[] parameters ) { var context = new GeneratorContext(typeContext) { Generator = generator, InterfaceMethod = interfaceMethod, Parameters = proxyMethod.GetParameters().Select(x => new ParamInfo(x)).ToArray() }; Type fieldType; if (proxyMethod is MethodInfo meth) { context.Method = meth; var returnType = meth.ReturnType; if (returnType.IsByRef) { context.ReturnType = returnType; } else { if (returnType == typeof(void)) { context.ReturnType = returnType; context.CallerType = CallerType.Void; fieldType = typeof(VoidCaller); } else if (!meth.IsDefined(typeof(StateMachineAttribute))) { context.ReturnType = returnType; context.CallerType = CallerType.Return; fieldType = typeof(ReturnCaller <>).MakeGenericType(returnType); } else if (returnType == typeof(Task)) { context.ReturnType = null; context.CallerType = CallerType.Task; fieldType = typeof(TaskCaller); } else if (returnType.IsGenericType) { var type = returnType.GetGenericTypeDefinition(); context.ReturnType = returnType.GetGenericArguments()[0]; if (type == typeof(Task <>)) { context.CallerType = CallerType.TaskOfT; fieldType = typeof(TaskCaller <>).MakeGenericType(context.ReturnType); } else if (type == typeof(ValueTask <>)) { context.CallerType = CallerType.ValueTaskOfT; fieldType = typeof(ValueTaskCaller <>).MakeGenericType(context.ReturnType); } else { throw new InvalidOperationException("function return value error!"); } } else { throw new InvalidOperationException("function return value error!"); } context.Caller = context.TypeBuilder.DefineField($"<>_caller{context.Token}", fieldType, FieldAttributes.Private); context.MethodBuilder = (MethodBuilder)builder; } } else if (proxyMethod is ConstructorInfo ctor) { context.Constructor = ctor; context.ReturnType = null; context.CallerType = CallerType.Ctor; context.Caller = context.TypeBuilder.DefineField($"<>_caller{context.Token}", typeof(VoidCaller), FieldAttributes.Private); context.ConstructorBuilder = (ConstructorBuilder)builder; } return(context); }
public abstract void Generate(GeneratorTypeContext context);
private void GeneratorConstructor( ConstructorBuilder methodBuilder, ConstructorInfo constructor, ILGenerator ctorGenerator, GeneratorTypeContext context, ParameterInfo[] parameters, bool isIntercept) { // 初始化 // Ldarg_0 一般是方法开始的第一个指令 ctorGenerator.Emit(OpCodes.Ldarg_0); ctorGenerator.Emit(OpCodes.Call, context.InitMethod); if (context.InterfaceType != null) { ctorGenerator.Emit(OpCodes.Ldarg_0); ctorGenerator.Emit(OpCodes.Call, ReflectionInfoProvider.ObjectConstructor); ctorGenerator.Emit(OpCodes.Ldarg_0); if (constructor == null && context.ClassType.IsValueType) { ctorGenerator.DeclareLocal(context.ClassType); ctorGenerator.Emit(OpCodes.Ldloca_S, 0); ctorGenerator.Emit(OpCodes.Initobj, context.ClassType); ctorGenerator.Emit(OpCodes.Ldloc_0); } else { for (var i = 1; i <= parameters.Length; i++) { ctorGenerator.Emit(OpCodes.Ldarg_S, i); } ctorGenerator.Emit(OpCodes.Newobj, constructor); } if (context.ClassType.IsValueType) { ctorGenerator.Emit(OpCodes.Box, context.ClassType); } ctorGenerator.Emit(OpCodes.Stfld, context.Interface); } else { if (isIntercept) { context.MethodHandles.Add(constructor.MethodHandle); // 调用基类构造函数 base(x) // 注:这里的调用位置在C#代码中无法表示,因为在C#中调用基类构造函数必须在方法参数列表之后 GenerateMethod(methodBuilder, constructor, null, ctorGenerator, context, parameters); } else { ctorGenerator.Emit(OpCodes.Ldarg_0); for (var i = 1; i <= parameters.Length; i++) { ctorGenerator.Emit(OpCodes.Ldarg_S, i); } ctorGenerator.Emit(OpCodes.Call, constructor); } } ctorGenerator.Emit(OpCodes.Ret); }
public override void Generate(GeneratorTypeContext context) { GenerateInit(context); var classType = context.ClassType; var typeBuilder = context.TypeBuilder; bool hasClassIntercept = classType.HasInterceptAttribute(); foreach (var ctor in classType.GetConstructors( BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ).Where( x => x.IsPublic || x.IsFamily || !(x.IsAssembly || x.IsFamilyAndAssembly || x.IsFamilyOrAssembly) )) { var baseParameterInfos = ctor.GetParameters(); var parameters = baseParameterInfos .Select(x => x.ParameterType) .ToArray(); // 定义构造函数 ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.HasThis, parameters ); bool isIntercept = true; if (ctor.IsDefined(typeof(NonInterceptAttribute))) { isIntercept = false; } if (!ctor.HasDefineInterceptAttribute() && !hasClassIntercept) { isIntercept = false; } constructorBuilder.SetMethodParameters(baseParameterInfos); ILGenerator ctorGenerator = constructorBuilder.GetILGenerator(); GeneratorConstructor( constructorBuilder, ctor, ctorGenerator, context, baseParameterInfos, isIntercept ); } if (context.InterfaceType != null && context.ClassType.IsValueType) { ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.HasThis, null ); ILGenerator ctorGenerator = constructorBuilder.GetILGenerator(); GeneratorConstructor( constructorBuilder, null, ctorGenerator, context, null, false ); } }
private void GenerateInterface(GeneratorTypeContext context) { var interfaceType = context.InterfaceType; var impNames = interfaceType.GetMethods( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly ); var impImpNames = impNames.Select(x => x.Name); // 隐式接口实现方法名称 var expImpNames = impNames.Select(x => interfaceType.FullName + "." + x.Name); // 显示接口实现方法名称 var classType = context.ClassType; var typeBuilder = context.TypeBuilder; bool hasClassIntercept = classType.HasInterceptAttribute(); bool hasInterfaceIntercept = interfaceType.HasInterceptAttribute(); var interfaceMethods = interfaceType.GetMethods( BindingFlags.Public | BindingFlags.Instance //BindingFlags.DeclaredOnly ); foreach (var proxyMethod in classType.GetMethods( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ).Where( x => x.IsVirtual )) { //if (proxyMethod.IsDefined(typeof(NonInterceptAttribute))) //{ // continue; //} if (!impImpNames.Contains(proxyMethod.Name) && !expImpNames.Contains(proxyMethod.Name)) { continue; } //if (!proxyMethod.HasDefineInterceptAttribute() && !hasClassIntercept && !hasInterfaceIntercept) //{ // continue; //} context.MethodHandles.Add(proxyMethod.MethodHandle); var baseParameterInfos = proxyMethod.GetParameters(); // 定义方法 MethodBuilder methodBuilder = typeBuilder.DefineMethod( interfaceType.FullName + "." + proxyMethod.Name, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.HasThis | CallingConventions.Standard, proxyMethod.ReturnType, baseParameterInfos.Select(x => x.ParameterType).ToArray() ); methodBuilder.SetReturnType(proxyMethod.ReturnType); methodBuilder.SetMethodParameters(proxyMethod, baseParameterInfos); ILGenerator methodGenerator = methodBuilder.GetILGenerator(); var dotIndex = proxyMethod.Name.LastIndexOf('.'); var interfaceMethod = impNames.First(x => x.Name == proxyMethod.Name.Substring(dotIndex == -1 ? 0 : dotIndex)); GenerateMethod(methodBuilder, proxyMethod, interfaceMethod, methodGenerator, context, baseParameterInfos); typeBuilder.DefineMethodOverride(methodBuilder, interfaceMethod); } }