private void GenerateRpcExecuteInformation(TypeBuilder typeBuilder, ImplementationRequest request, MethodGenerationContext generationContext, MethodInfo methodInfo, Attribute[] attributes, HttpMethod method) { var fieldName = "EasyRpcInfo_" + methodInfo.Name; generationContext.ExecutionInfoField = typeBuilder.DefineField(fieldName, typeof(RpcExecuteInformation), FieldAttributes.Static | FieldAttributes.Public); generationContext.ExecuteInformation = new RpcExecuteInformation { Method = method, ClientProvider = request.ClientProvider, Serializer = request.DefaultSerializer }; generationContext.GenerationContext.FinalizeTypeActions.Add(t => { var field = t.GetField(fieldName, BindingFlags.Static | BindingFlags.Public); if (field == null) { throw new Exception($"Could not locate static field {fieldName} on {t.Name} for interface {methodInfo.DeclaringType?.Name}.{methodInfo.Name}"); } field.SetValue(null, generationContext.ExecuteInformation); }); }
private void PopulateGenerationContext(TypeBuilder typeBuilder, ImplementationRequest request, MethodGenerationContext generationContext, MethodInfo methodInfo, Attribute[] attributes) { HttpMethod method = HttpMethod.Post; if (request.ExposeDefaultMethod == ExposeDefaultMethod.PostOnly) { var classNameString = methodInfo.DeclaringType?.Name; var methodNameString = methodInfo.Name; if (request.NamingConventionService != null) { classNameString = request.NamingConventionService.GetNameForType(methodInfo.DeclaringType); methodNameString = request.NamingConventionService.GetMethodName(methodInfo); } generationContext.PathTemplate = request.BasePath + classNameString + "/" + methodNameString; generationContext.BodyParameters = new List <ParameterInfo>(); generationContext.BodyParameters.AddRange(methodInfo.GetParameters()); } else { throw new NotImplementedException(); } GenerateRpcExecuteInformation(typeBuilder, request, generationContext, methodInfo, attributes, method); }
private void GenerateMethodAsDefaultExpose(TypeBuilder typeBuilder, ImplementationRequest request, MethodGenerationContext generationContext, MethodInfo methodInfo, Attribute[] attributes) { PopulateGenerationContext(typeBuilder, request, generationContext, methodInfo, attributes); GenerateMethodImplementation(typeBuilder, request, generationContext, methodInfo, attributes); }
protected virtual TypeBuilder CreateTypeBuilder(ImplementationRequest request, GenerationContext generationContext) { var interfaceType = _moduleBuilder.DefineType("ClientInterfaceProxy" + _proxyCount, TypeAttributes.Public); interfaceType.AddInterfaceImplementation(request.InterfaceType); return(interfaceType); }
private void GenerateConstructorIL(TypeBuilder typeBuilder, ImplementationRequest request, GenerationContext generationContext, ConstructorBuilder constructor) { var ilGenerator = constructor.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Stfld, generationContext.RpcExecutionServiceField); ilGenerator.Emit(OpCodes.Ret); }
private void GenerateMethods(TypeBuilder typeBuilder, ImplementationRequest request, GenerationContext generationContext) { foreach (var methodInfo in request.InterfaceType.GetMethods(BindingFlags.Instance | BindingFlags.Public)) { var methodGenerationContext = new MethodGenerationContext(generationContext); GenerateMethod(typeBuilder, request, methodGenerationContext, methodInfo); } }
private void GenerateConstructor(TypeBuilder typeBuilder, ImplementationRequest request, GenerationContext generationContext) { generationContext.RpcExecutionServiceField = typeBuilder.DefineField("_rpcExecutionService", typeof(IRpcExecutionService), FieldAttributes.Private); var constructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] { typeof(IRpcExecutionService) }); constructor.DefineParameter(1, ParameterAttributes.None, "rpcExecutionService"); GenerateConstructorIL(typeBuilder, request, generationContext, constructor); }
private void GenerateMethodImplementation(TypeBuilder typeBuilder, ImplementationRequest request, MethodGenerationContext generationContext, MethodInfo methodInfo, Attribute[] attributes) { var parameters = methodInfo.GetParameters(); var methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.NewSlot; var methodBuilder = typeBuilder.DefineMethod(methodInfo.Name, methodAttributes, CallingConventions.Standard, methodInfo.ReturnType, parameters.Select(p => p.ParameterType).ToArray()); GenerateMethodImplementationIL(typeBuilder, request, generationContext, methodInfo, attributes, methodBuilder); }
private void GenerateMethod(TypeBuilder typeBuilder, ImplementationRequest request, MethodGenerationContext generationContext, MethodInfo methodInfo) { var attributes = methodInfo.GetCustomAttributes <Attribute>(true).ToArray(); if (attributes.Any(a => a is IgnoreMethodAttribute)) { return; } var pathAttribute = attributes.FirstOrDefault(a => a is IPathAttribute); if (pathAttribute != null) { GenerateMethodFromPathAttribute(typeBuilder, request, generationContext, methodInfo, attributes, pathAttribute); } else { GenerateMethodAsDefaultExpose(typeBuilder, request, generationContext, methodInfo, attributes); } }
private void GenerateBodyVariable(TypeBuilder typeBuilder, ImplementationRequest request, ILGenerator il, MethodGenerationContext generationContext, MethodInfo methodInfo) { // single parameter is loaded directly from the parameter no need for a local variable if (request.SingleParameterToBody && generationContext.BodyParameters.Count == 1) { return; } var serializedType = _serializationTypeCreator.CreateSerializationTypeForMethod(generationContext.BodyParameters); var bodyVariable = il.DeclareLocal(serializedType); generationContext.BodyVariable = bodyVariable; var constructor = serializedType.GetConstructor(new Type[0]); il.Emit(OpCodes.Newobj, constructor); il.Emit(OpCodes.Stloc, generationContext.BodyVariable); foreach (var bodyParameter in generationContext.BodyParameters) { var propertyInfo = serializedType.GetProperty(bodyParameter.Name); var setMethod = propertyInfo?.GetSetMethod(); if (setMethod == null) { // should never get here as the type is auto generated throw new Exception($"Could not find set method on serialized type {serializedType.Name} property {bodyParameter.Name}"); } il.Emit(OpCodes.Ldloc, bodyVariable); il.EmitLoadArg(bodyParameter.Position + 1); il.EmitMethodCall(setMethod); } }
private void GenerateMethodImplementationIL(TypeBuilder typeBuilder, ImplementationRequest request, MethodGenerationContext generationContext, MethodInfo methodInfo, Attribute[] attributes, MethodBuilder methodBuilder) { var il = methodBuilder.GetILGenerator(); if (generationContext.UrlParameters != null && generationContext.UrlParameters.Count > 0) { throw new NotImplementedException(); } if (generationContext.BodyParameters != null && generationContext.BodyParameters.Count > 0) { GenerateBodyVariable(typeBuilder, request, il, generationContext, methodInfo); } GenerateRpcExecutionMethodCall(generationContext, methodInfo, il); il.Emit(OpCodes.Ret); }
public Type GenerateImplementationForInterface(ImplementationRequest request) { lock (_lock) { _proxyCount++; var generationContext = new GenerationContext(); var typeBuilder = CreateTypeBuilder(request, generationContext); GenerateConstructor(typeBuilder, request, generationContext); GenerateMethods(typeBuilder, request, generationContext); var type = typeBuilder.CreateTypeInfo().AsType(); foreach (var finalizeTypeAction in generationContext.FinalizeTypeActions) { finalizeTypeAction(type); } return(type); } }
private void GenerateMethodFromPathAttribute(TypeBuilder typeBuilder, ImplementationRequest request, MethodGenerationContext generationContext, MethodInfo methodInfo, Attribute[] attributes, Attribute pathAttribute) { }