private void BuildMethod(IndentBuilder classBuilder, MethodInfo method) { var isAsyncCall = typeof(Task).IsAssignableFrom(method.ReturnType); var returnType = method.ReturnType; if (isAsyncCall && method.ReturnType.IsConstructedGenericType) { returnType = method.ReturnType.GetGenericArguments()[0]; } var isVoid = returnType == typeof(void) || (isAsyncCall && !method.ReturnType.IsConstructedGenericType); // Write the method declaration classBuilder.Append("public "); if (isAsyncCall) { classBuilder.Append("async "); classBuilder.Append(typeof(Task).FullName); if (!isVoid) { classBuilder.Append($"<{CompilerUtils.ToCompilableName(returnType)}>"); } } else { classBuilder.Append(isVoid ? "void" : CompilerUtils.ToCompilableName(returnType)); } var attribute = method.GetCustomAttribute <HttpMethodAttribute>(); classBuilder.Append($" {method.Name}("); classBuilder.Append(string.Join(", ", method.GetParameters().Select(CompilerUtils.ToParameterDeclaration))); classBuilder.AppendLine(")"); classBuilder.AppendLine("{"); using (var methodBuilder = classBuilder.Indent()) { methodBuilder.AppendLine( "var 仮variables = new System.Collections.Generic.Dictionary<string,object>();"); methodBuilder.AppendLine( "var 仮reqParams = new System.Collections.Generic.Dictionary<string,string>();"); var contentHeaders = new Dictionary <string, ParameterInfo>(); var requestHeaders = new Dictionary <string, ParameterInfo>(); var responseHeaders = new Dictionary <string, ParameterInfo>(); ParameterInfo bodyParam = null; BodyAttribute bodyAttr = null; foreach (var parameter in method.GetParameters()) { AttributeInterpreter.InterpretPathValue(parameter, methodBuilder); AttributeInterpreter.InterpretRequestHeader(parameter, requestHeaders, contentHeaders); AttributeInterpreter.InterpretBodyParameter(parameter, ref bodyParam, ref bodyAttr); AttributeInterpreter.InterpretRequestParameter(parameter, methodBuilder); AttributeInterpreter.InterpretResponseHeaderInParameters(parameter, isAsyncCall, ref responseHeaders); } methodBuilder.AppendLine( $"var 仮request = CreateRequest({CompilerUtils.ToCompilableName(attribute.Method)}, \"{attribute.Path}\", 仮variables, 仮reqParams);"); var hasContent = AttributeInterpreter.CreateContentObjectIfSpecified(bodyAttr, bodyParam, methodBuilder); foreach (var entry in requestHeaders) { methodBuilder.AppendLine( $"仮request.Headers.Add(\"{entry.Key}\", {entry.Value.Name}{(entry.Value.ParameterType.IsClass ? "?" : "")}.ToString());"); } if (hasContent) { // when setting content we can apply the contentHeaders foreach (var entry in contentHeaders) { methodBuilder.AppendLine( $"仮content.Headers.Add(\"{entry.Key}\", {entry.Value.Name}{(entry.Value.ParameterType.IsClass ? "?" : "")}.ToString());"); } methodBuilder.AppendLine("仮request.Content = 仮content;"); } methodBuilder.AppendLine(isAsyncCall ? "var 仮response = await InvokeAsync(仮request);" : "var 仮response = Invoke(仮request);"); foreach (var entry in responseHeaders) { methodBuilder.AppendLine( $"{entry.Value.Name} = GetHeaderValue<{CompilerUtils.ToCompilableName(entry.Value.ParameterType)}>(仮response, \"{entry.Key}\");"); } if (!isVoid) { var returnBodyAttribute = method.ReturnParameter?.GetCustomAttribute <BodyAttribute>(); var returnResponseAttribute = method.ReturnParameter?.GetCustomAttribute <ResponseHeaderAttribute>(); if (returnResponseAttribute != null && returnBodyAttribute != null) { throw new WebServiceCompileException( $"Cannot have different types of response attributes. You had [{string.Join(", ", "Body", "ResponseHeader")}]"); } if (returnResponseAttribute != null) { AttributeInterpreter.ReturnResponseHeader(returnResponseAttribute, returnType, methodBuilder); } else { if (returnBodyAttribute == null) { returnBodyAttribute = new BodyAttribute(); } AttributeInterpreter.ReturnContentObject(returnBodyAttribute, returnType, isAsyncCall, methodBuilder); } } } classBuilder.AppendLine("}"); }
private void BuildMethod(IndentBuilder classBuilder, MethodInfo method, string hystrixCommandName) { var isAsyncCall = typeof(Task).IsAssignableFrom(method.ReturnType); var returnType = method.ReturnType; if (isAsyncCall && method.ReturnType.IsConstructedGenericType) { returnType = method.ReturnType.GetGenericArguments()[0]; } var isVoid = returnType == typeof(void) || (isAsyncCall && !method.ReturnType.IsConstructedGenericType); // Write the method declaration classBuilder.Append("public "); if (isAsyncCall) { classBuilder.Append("async "); classBuilder.Append(typeof(Task).FullName); if (!isVoid) { classBuilder.Append($"<{CompilerUtils.ToCompilableName(returnType)}>"); } } else { classBuilder.Append(isVoid ? "void" : CompilerUtils.ToCompilableName(returnType)); } classBuilder.Append($" {method.Name}("); classBuilder.Append(string.Join(", ", method.GetParameters().Select(CompilerUtils.ToParameterDeclaration))); classBuilder.AppendLine(")"); classBuilder.AppendLine("{"); using (var methodBuilder = classBuilder.Indent()) { methodBuilder.Append($"var 仮command = new {hystrixCommandName}(this, 仮fallback, "); foreach (var inParam in method.GetParameters().Where(p => !p.IsOut)) { methodBuilder.Append($"{CompilerUtils.ToParameterUsage(inParam)}, "); } methodBuilder.AppendLine(" 仮logger);"); methodBuilder.Append(isVoid ? string.Empty : "var 仮value = "); methodBuilder.AppendLine(isAsyncCall ? "await 仮command.ExecuteAsync();" : "仮command.Execute();"); foreach (var outParam in method.GetParameters().Where(p => p.IsOut)) { methodBuilder.AppendLine($"{outParam.Name} = 仮command.{outParam.Name};"); } if (!isVoid) { methodBuilder.AppendLine("return 仮value;"); } } classBuilder.AppendLine("}"); }