MethodInfo GetInvokeMethod(RequestMappingBaseAttribute requestMapping, Type returnType, bool async) { MethodInfo httpClientMethod; switch (requestMapping.GetMethod()?.ToUpper() ?? "") { case "GET": httpClientMethod = async ? FeignClientProxyService.HTTP_GET_ASYNC_METHOD : FeignClientProxyService.HTTP_GET_METHOD; break; case "POST": httpClientMethod = async ? FeignClientProxyService.HTTP_POST_ASYNC_METHOD : FeignClientProxyService.HTTP_POST_METHOD; break; case "PUT": httpClientMethod = async ? FeignClientProxyService.HTTP_PUT_ASYNC_METHOD : FeignClientProxyService.HTTP_PUT_METHOD; break; case "DELETE": httpClientMethod = async ? FeignClientProxyService.HTTP_DELETE_ASYNC_METHOD : FeignClientProxyService.HTTP_DELETE_METHOD; break; default: throw new ArgumentException("httpMethod error"); } if (returnType == null || returnType == typeof(void)) { return(httpClientMethod.MakeGenericMethod(typeof(Newtonsoft.Json.Linq.JObject))); } return(httpClientMethod.MakeGenericMethod(returnType)); }
/// <summary> /// 是否支持RequestContent /// </summary> /// <param name="method"></param> /// <param name="requestMappingBaseAttribute"></param> /// <returns></returns> protected bool SupportRequestContent(MethodInfo method, RequestMappingBaseAttribute requestMappingBaseAttribute) { return (requestMappingBaseAttribute.IsHttpMethod(HttpMethod.Post) || requestMappingBaseAttribute.IsHttpMethod(HttpMethod.Put) || requestMappingBaseAttribute.IsHttpMethod(HttpMethod.Delete)); }
MethodInfo GetInvokeMethod(MethodInfo method, RequestMappingBaseAttribute requestMapping) { Type returnType = GetReturnType(method); if (IsTaskMethod(method)) { return(GetInvokeMethod(requestMapping, returnType, true)); } return(GetInvokeMethod(requestMapping, returnType, false)); }
protected MethodInfo GetInvokeMethod(MethodInfo method, RequestMappingBaseAttribute requestMapping) { if (method.IsTaskMethod()) { if (method.ReturnType.IsGenericType) { return(GetInvokeMethod(requestMapping, method.ReturnType.GenericTypeArguments[0], true)); } return(GetInvokeMethod(requestMapping, method.ReturnType, true)); } return(GetInvokeMethod(requestMapping, method.ReturnType, false)); }
/// <summary> /// 获取调用的Send方法 /// <see cref="Proxy.FeignClientHttpProxy{TService}.SendAsync(FeignClientHttpRequest)"/> /// <see cref="Proxy.FeignClientHttpProxy{TService}.SendAsync{TResult}(FeignClientHttpRequest)"/> /// <see cref="Proxy.FeignClientHttpProxy{TService}.Send(FeignClientHttpRequest)"/> /// <see cref="Proxy.FeignClientHttpProxy{TService}.Send{TResult}(FeignClientHttpRequest)"/> /// </summary> /// <param name="serviceType"></param> /// <param name="method"></param> /// <param name="requestMapping"></param> /// <returns></returns> protected MethodInfo GetInvokeMethod(Type serviceType, MethodInfo method, RequestMappingBaseAttribute requestMapping) { return(GetInvokeMethod(serviceType, requestMapping, GetReturnType(method), method.IsTaskMethod())); //if (method.IsTaskMethod()) //{ // if (method.ReturnType.IsGenericType) // { // return GetInvokeMethod(serviceType, requestMapping, method.ReturnType.GenericTypeArguments[0], true); // } // return GetInvokeMethod(serviceType, requestMapping, method.ReturnType, true); //} //return GetInvokeMethod(serviceType, requestMapping, method.ReturnType, false); }
protected virtual MethodInfo GetInvokeMethod(Type serviceType, RequestMappingBaseAttribute requestMapping, Type returnType, bool async) { MethodInfo httpClientMethod; bool isGeneric = !(returnType == null || returnType == typeof(void) || returnType == typeof(Task)); if (isGeneric) { httpClientMethod = async ? FeignClientHttpProxy <object> .GetHttpSendAsyncGenericMethod(serviceType) : FeignClientHttpProxy <object> .GetHttpSendGenericMethod(serviceType); } else { httpClientMethod = async ? FeignClientHttpProxy <object> .GetHttpSendAsyncMethod(serviceType) : FeignClientHttpProxy <object> .GetHttpSendMethod(serviceType); } if (isGeneric) { return(httpClientMethod.MakeGenericMethod(returnType)); } return(httpClientMethod); }
protected virtual MethodInfo GetInvokeMethod(RequestMappingBaseAttribute requestMapping, Type returnType, bool async) { MethodInfo httpClientMethod; bool isGeneric = !(returnType == null || returnType == typeof(void) || returnType == typeof(Task)); if (isGeneric) { httpClientMethod = async ? FeignClientHttpProxy.HTTP_SEND_ASYNC_GENERIC_METHOD : FeignClientHttpProxy.HTTP_SEND_GENERIC_METHOD; } else { httpClientMethod = async ? FeignClientHttpProxy.HTTP_SEND_ASYNC_METHOD : FeignClientHttpProxy.HTTP_SEND_METHOD; } if (isGeneric) { return(httpClientMethod.MakeGenericMethod(returnType)); } return(httpClientMethod); }
protected override MethodInfo GetInvokeMethod(Type serviceType, RequestMappingBaseAttribute requestMapping, Type returnType, bool async) { MethodInfo httpClientMethod; bool isGeneric = !(returnType == null || returnType == typeof(void) || returnType == typeof(Task)); if (isGeneric) { //httpClientMethod = async ? FallbackFeignClientHttpProxy<object, object>.HTTP_SEND_ASYNC_GENERIC_METHOD_FALLBACK : FallbackFeignClientHttpProxy<object, object>.HTTP_SEND_GENERIC_METHOD_FALLBACK; httpClientMethod = async ? FallbackFeignClientHttpProxy <object, object> .GetHttpSendAsyncGenericFallbackMethod(serviceType, serviceType) : FallbackFeignClientHttpProxy <object, object> .GetHttpSendGenericFallbackMethod(serviceType, serviceType); } else { //httpClientMethod = async ? FallbackFeignClientHttpProxy<object, object>.HTTP_SEND_ASYNC_METHOD_FALLBACK : FallbackFeignClientHttpProxy<object, object>.HTTP_SEND_METHOD_FALLBACK; httpClientMethod = async ? FallbackFeignClientHttpProxy <object, object> .GetHttpSendAsyncFallbackMethod(serviceType, serviceType) : FallbackFeignClientHttpProxy <object, object> .GetHttpSendFallbackMethod(serviceType, serviceType); } if (isGeneric) { return(httpClientMethod.MakeGenericMethod(returnType)); } return(httpClientMethod); }
void BuildMethod(TypeBuilder typeBuilder, Type serviceType, MethodInfo method, FeignClientAttribute feignClientAttribute, RequestMappingBaseAttribute requestMapping) { MethodBuilder methodBuilder = CreateMethodBuilder(typeBuilder, method); ILGenerator iLGenerator = methodBuilder.GetILGenerator(); if (requestMapping == null) { iLGenerator.Emit(OpCodes.Newobj, typeof(NotSupportedException).GetConstructor(Type.EmptyTypes)); iLGenerator.Emit(OpCodes.Throw); return; } string uri = requestMapping.Value ?? ""; LocalBuilder local_Uri = iLGenerator.DeclareLocal(typeof(string)); // uri LocalBuilder local_OldValue = iLGenerator.DeclareLocal(typeof(string)); // temp iLGenerator.Emit(OpCodes.Ldstr, uri); iLGenerator.Emit(OpCodes.Stloc, local_Uri); List <EmitRequestContent> emitRequestContents = EmitParameter(iLGenerator, method, local_Uri, local_OldValue); EmitCallMethod(typeBuilder, methodBuilder, iLGenerator, serviceType, method, requestMapping, local_Uri, emitRequestContents); }
protected LocalBuilder DefineFeignClientRequest(TypeBuilder typeBuilder, Type serviceType, ILGenerator iLGenerator, LocalBuilder uri, RequestMappingBaseAttribute requestMapping, List <EmitRequestContent> emitRequestContents, MethodInfo methodInfo) { LocalBuilder localBuilder = iLGenerator.DeclareLocal(typeof(FeignClientRequest)); // baseUrl EmitBaseUrl(iLGenerator); //mapping uri if (requestMapping.Value == null) { iLGenerator.Emit(OpCodes.Ldnull); } else { iLGenerator.Emit(OpCodes.Ldstr, requestMapping.Value); } //uri iLGenerator.Emit(OpCodes.Ldloc, uri); //httpMethod iLGenerator.Emit(OpCodes.Ldstr, requestMapping.GetMethod()); //contentType string contentType = requestMapping.ContentType; if (string.IsNullOrWhiteSpace(contentType) && serviceType.IsDefined(typeof(RequestMappingAttribute))) { contentType = serviceType.GetCustomAttribute <RequestMappingAttribute>().ContentType; } if (contentType == null) { iLGenerator.Emit(OpCodes.Ldnull); } else { iLGenerator.Emit(OpCodes.Ldstr, contentType); } //requestContent if (emitRequestContents != null && emitRequestContents.Count > 0) { if (emitRequestContents.Count == 1) { if (typeof(IRequestFile).IsAssignableFrom(emitRequestContents[0].Parameter.ParameterType)) { EmitFeignClientMultipartRequestContent(iLGenerator, emitRequestContents); } else { EmitFeignClientRequestContent(iLGenerator, emitRequestContents[0], null); } } else if (emitRequestContents.Any(s => !s.SupportMultipart)) { throw new NotSupportedException("最多只支持一个RequestContent"); } else { EmitFeignClientMultipartRequestContent(iLGenerator, emitRequestContents); } } else { iLGenerator.Emit(OpCodes.Ldnull); } //method // method=null LocalBuilder methodInfoLocalBuilder = iLGenerator.DeclareLocal(typeof(MethodInfo)); iLGenerator.Emit(OpCodes.Ldnull); iLGenerator.Emit(OpCodes.Stloc, methodInfoLocalBuilder); Label newFeingClientRequestLabel = iLGenerator.DefineLabel(); #region if (base.FeignOptions.IncludeMethodMetadata) set the call method PropertyInfo feignOptionsProperty = typeBuilder.BaseType.GetProperty("FeignOptions", BindingFlags.Instance | BindingFlags.NonPublic); PropertyInfo includeMethodMetadataProperty = feignOptionsProperty.PropertyType.GetProperty("IncludeMethodMetadata"); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Call, feignOptionsProperty.GetMethod); iLGenerator.Emit(OpCodes.Call, includeMethodMetadataProperty.GetMethod); iLGenerator.Emit(OpCodes.Ldc_I4, 1); iLGenerator.Emit(OpCodes.Ceq); iLGenerator.Emit(OpCodes.Brfalse_S, newFeingClientRequestLabel); ReflectionHelper.EmitMethodInfo(iLGenerator, methodInfo); iLGenerator.Emit(OpCodes.Stloc, methodInfoLocalBuilder); #endregion iLGenerator.MarkLabel(newFeingClientRequestLabel); iLGenerator.Emit(OpCodes.Ldloc, methodInfoLocalBuilder); iLGenerator.Emit(OpCodes.Newobj, typeof(FeignClientRequest).GetConstructors()[0]); iLGenerator.Emit(OpCodes.Stloc, localBuilder); return(localBuilder); }
FeignClientMethodInfo BuildMethod(TypeBuilder typeBuilder, Type serviceType, MethodInfo method, FeignClientAttribute feignClientAttribute, RequestMappingBaseAttribute requestMapping) { FeignClientMethodInfo feignClientMethodInfo = new FeignClientMethodInfo { MethodId = GetMethodId(method), MethodMetadata = method }; //创建方法 MethodBuilder methodBuilder = CreateMethodBuilder(typeBuilder, method); ILGenerator iLGenerator = methodBuilder.GetILGenerator(); if (requestMapping == null) { //如果找不到mapping,抛出 NotSupportedException 异常 iLGenerator.Emit(OpCodes.Newobj, typeof(NotSupportedException).GetConstructor(Type.EmptyTypes)); iLGenerator.Emit(OpCodes.Throw); return(new FeignClientMethodInfo { MethodId = GetMethodId(method), MethodMetadata = method }); } string uri = requestMapping.Value ?? ""; LocalBuilder local_Uri = iLGenerator.DeclareLocal(typeof(string)); // 定义uri iLGenerator.Emit(OpCodes.Ldstr, uri); iLGenerator.Emit(OpCodes.Stloc, local_Uri); List <EmitRequestContent> emitRequestContents = EmitParameter(typeBuilder, requestMapping, iLGenerator, method, local_Uri); EmitCallMethod(typeBuilder, methodBuilder, iLGenerator, serviceType, feignClientMethodInfo, requestMapping, local_Uri, emitRequestContents); methodBuilder.CopyCustomAttributes(method); return(feignClientMethodInfo); }
/// <summary> /// 处理参数 /// </summary> /// <param name="typeBuilder"></param> /// <param name="requestMapping"></param> /// <param name="iLGenerator"></param> /// <param name="method"></param> /// <param name="uri"></param> /// <returns></returns> protected List <EmitRequestContent> EmitParameter(TypeBuilder typeBuilder, RequestMappingBaseAttribute requestMapping, ILGenerator iLGenerator, MethodInfo method, LocalBuilder uri) { int index = 0; List <EmitRequestContent> emitRequestContents = new List <EmitRequestContent>(); foreach (var parameterInfo in method.GetParameters()) { index++; if (parameterInfo.GetCustomAttributes().Any(s => s is INotRequestParameter)) { continue; } if (typeof(IHttpRequestFileForm).IsAssignableFrom(parameterInfo.ParameterType)) { emitRequestContents.Add(new EmitRequestContent { MediaType = Constants.MediaTypes.MULTIPART_FORMDATA, Parameter = parameterInfo, SupportMultipart = false, ParameterIndex = index }); continue; } if (typeof(IHttpRequestFile).IsAssignableFrom(parameterInfo.ParameterType)) { emitRequestContents.Add(new EmitRequestContent { MediaType = Constants.MediaTypes.FORMDATA, Parameter = parameterInfo, SupportMultipart = true, ParameterIndex = index }); continue; } if (parameterInfo.IsDefined(typeof(RequestBodyAttribute))) { emitRequestContents.Add(new EmitRequestContent { MediaType = Constants.MediaTypes.APPLICATION_JSON, Parameter = parameterInfo, SupportMultipart = false, ParameterIndex = index }); continue; } if (parameterInfo.IsDefined(typeof(RequestFormAttribute))) { emitRequestContents.Add(new EmitRequestContent { MediaType = Constants.MediaTypes.APPLICATION_FORM_URLENCODED, Parameter = parameterInfo, SupportMultipart = true, ParameterIndex = index }); continue; } MethodInfo replaceValueMethod; string name; if (parameterInfo.IsDefined(typeof(RequestParamAttribute))) { //如果是 HttpGet , 拼接到url上 if (requestMapping.IsHttpMethod(HttpMethod.Get) || requestMapping.IsHttpMethod(HttpMethod.Head)) { name = parameterInfo.GetCustomAttribute <RequestParamAttribute>().Name ?? parameterInfo.Name; //replaceValueMethod = ReplaceRequestParamMethod; replaceValueMethod = GetReplaceRequestQueryMethod(typeBuilder, parameterInfo.ParameterType); } else { emitRequestContents.Add(new EmitRequestContent { MediaType = Constants.MediaTypes.APPLICATION_FORM_URLENCODED, Parameter = parameterInfo, SupportMultipart = true, ParameterIndex = index }); continue; } } else if (parameterInfo.IsDefined(typeof(RequestQueryAttribute))) { name = parameterInfo.Name; //replaceValueMethod = ReplaceRequestQueryMethod; replaceValueMethod = GetReplaceRequestQueryMethod(typeBuilder, parameterInfo.ParameterType); } else { name = parameterInfo.IsDefined(typeof(PathVariableAttribute)) ? parameterInfo.GetCustomAttribute <PathVariableAttribute>().Name : parameterInfo.Name; //replaceValueMethod = ReplacePathVariableMethod; replaceValueMethod = GetReplacePathVariableMethod(typeBuilder, parameterInfo.ParameterType); } if (string.IsNullOrWhiteSpace(name)) { name = parameterInfo.Name; } iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldloc, uri); iLGenerator.Emit(OpCodes.Ldstr, name); iLGenerator.Emit(OpCodes.Ldarg_S, index); iLGenerator.Emit(OpCodes.Call, replaceValueMethod); iLGenerator.Emit(OpCodes.Stloc, uri); } return(emitRequestContents); }
/// <summary> /// 获取调用的Send方法 /// <see cref="Proxy.FeignClientHttpProxy{TService}.SendAsync(FeignClientHttpRequest)"/> /// <see cref="Proxy.FeignClientHttpProxy{TService}.SendAsync{TResult}(FeignClientHttpRequest)"/> /// <see cref="Proxy.FeignClientHttpProxy{TService}.Send(FeignClientHttpRequest)"/> /// <see cref="Proxy.FeignClientHttpProxy{TService}.Send{TResult}(FeignClientHttpRequest)"/> /// </summary> /// <param name="serviceType"></param> /// <param name="method"></param> /// <param name="requestMapping"></param> /// <returns></returns> protected MethodInfo GetInvokeMethod(Type serviceType, MethodInfo method, RequestMappingBaseAttribute requestMapping) { return(GetInvokeMethod(serviceType, requestMapping, GetReturnType(method), method.IsTaskMethod())); }
/// <summary> /// 定义用于Send方法的FeignClientHttpRequest /// </summary> /// <param name="typeBuilder"></param> /// <param name="serviceType"></param> /// <param name="iLGenerator"></param> /// <param name="uri"></param> /// <param name="requestMapping"></param> /// <param name="emitRequestContents"></param> /// <param name="feignClientMethodInfo"></param> /// <returns></returns> protected LocalBuilder DefineFeignClientRequest(TypeBuilder typeBuilder, Type serviceType, ILGenerator iLGenerator, LocalBuilder uri, RequestMappingBaseAttribute requestMapping, List <EmitRequestContent> emitRequestContents, FeignClientMethodInfo feignClientMethodInfo) { LocalBuilder localBuilder = iLGenerator.DeclareLocal(typeof(FeignClientHttpRequest)); // baseUrl EmitBaseUrl(iLGenerator, serviceType); //mapping uri if (requestMapping.Value == null) { iLGenerator.Emit(OpCodes.Ldnull); } else { iLGenerator.Emit(OpCodes.Ldstr, requestMapping.Value); } //uri iLGenerator.Emit(OpCodes.Ldloc, uri); //httpMethod iLGenerator.Emit(OpCodes.Ldstr, requestMapping.GetMethod()); //contentType string contentType = requestMapping.ContentType; if (string.IsNullOrWhiteSpace(contentType) && serviceType.IsDefined(typeof(RequestMappingAttribute))) { contentType = serviceType.GetCustomAttribute <RequestMappingAttribute>().ContentType; } if (contentType == null) { iLGenerator.Emit(OpCodes.Ldnull); } else { iLGenerator.Emit(OpCodes.Ldstr, contentType); } //accept string accept = requestMapping.Accept; if (string.IsNullOrWhiteSpace(contentType) && serviceType.IsDefined(typeof(RequestMappingAttribute))) { accept = serviceType.GetCustomAttribute <RequestMappingAttribute>().Accept; } if (accept == null) { iLGenerator.Emit(OpCodes.Ldnull); } else { iLGenerator.Emit(OpCodes.Ldstr, accept); } //headers List <string> headers = new List <string>(); if (serviceType.IsDefined(typeof(HeadersAttribute), true)) { var serviceHeaders = serviceType.GetCustomAttribute <HeadersAttribute>().Headers; if (serviceHeaders != null) { headers.AddRange(serviceHeaders); } } if (feignClientMethodInfo.MethodMetadata.IsDefined(typeof(HeadersAttribute), true)) { var methodHeaders = feignClientMethodInfo.MethodMetadata.GetCustomAttribute <HeadersAttribute>().Headers; if (methodHeaders != null) { headers.AddRange(methodHeaders); } } if (headers.Count == 0) { iLGenerator.Emit(OpCodes.Ldnull); } else { iLGenerator.EmitStringArray(headers); } //requestContent if (emitRequestContents != null && emitRequestContents.Count > 0) { if (emitRequestContents.Count == 1) { if (typeof(IHttpRequestFile).IsAssignableFrom(emitRequestContents[0].Parameter.ParameterType)) { EmitFeignClientMultipartRequestContent(iLGenerator, emitRequestContents); } else { EmitFeignClientRequestContent(iLGenerator, emitRequestContents[0], null); } } else if (emitRequestContents.Any(s => !s.SupportMultipart)) { throw new NotSupportedException("最多只支持一个RequestContent \r\n " + feignClientMethodInfo.ToString()); } else { EmitFeignClientMultipartRequestContent(iLGenerator, emitRequestContents); } } else { iLGenerator.Emit(OpCodes.Ldnull); } #region new //feignClientMethodInfo //feignClientMethodInfo=null LocalBuilder feignClientMethodInfoLocalBuilder = iLGenerator.DeclareLocal(typeof(FeignClientMethodInfo)); iLGenerator.Emit(OpCodes.Newobj, typeof(FeignClientMethodInfo).GetConstructors()[0]); iLGenerator.Emit(OpCodes.Stloc, feignClientMethodInfoLocalBuilder); iLGenerator.Emit(OpCodes.Ldloc, feignClientMethodInfoLocalBuilder); iLGenerator.Emit(OpCodes.Ldstr, feignClientMethodInfo.MethodId); iLGenerator.Emit(OpCodes.Call, typeof(FeignClientMethodInfo).GetProperty("MethodId").SetMethod); #region ResultType //feignClientMethodInfo.ResultType=typeof(xx); ResultTypeAttribute resultTypeAttribute = feignClientMethodInfo.MethodMetadata.GetCustomAttribute <ResultTypeAttribute>(); Type returnType = GetReturnType(feignClientMethodInfo.MethodMetadata); if (returnType != null && resultTypeAttribute != null) { Type resultType = resultTypeAttribute.ConvertType(returnType); if (resultType != null) { iLGenerator.Emit(OpCodes.Ldloc, feignClientMethodInfoLocalBuilder); iLGenerator.EmitType(resultType); iLGenerator.Emit(OpCodes.Call, typeof(FeignClientMethodInfo).GetProperty("ResultType").SetMethod); } } #endregion Label newFeingClientRequestLabel = iLGenerator.DefineLabel(); #region if (base.FeignOptions.IncludeMethodMetadata) set the call method //这里获取方法元数据 PropertyInfo feignOptionsProperty = typeBuilder.BaseType.GetProperty("FeignOptions", BindingFlags.Instance | BindingFlags.NonPublic); PropertyInfo includeMethodMetadataProperty = feignOptionsProperty.PropertyType.GetProperty("IncludeMethodMetadata"); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Call, feignOptionsProperty.GetMethod); iLGenerator.Emit(OpCodes.Callvirt, includeMethodMetadataProperty.GetMethod); iLGenerator.Emit(OpCodes.Ldc_I4, 1); iLGenerator.Emit(OpCodes.Ceq); iLGenerator.Emit(OpCodes.Brfalse_S, newFeingClientRequestLabel); iLGenerator.Emit(OpCodes.Ldloc, feignClientMethodInfoLocalBuilder); iLGenerator.EmitMethodInfo(feignClientMethodInfo.MethodMetadata); iLGenerator.Emit(OpCodes.Call, typeof(FeignClientMethodInfo).GetProperty("MethodMetadata").SetMethod); #endregion //处理下 if GOTO iLGenerator.MarkLabel(newFeingClientRequestLabel); iLGenerator.Emit(OpCodes.Ldloc, feignClientMethodInfoLocalBuilder); iLGenerator.Emit(OpCodes.Newobj, typeof(FeignClientHttpRequest).GetConstructors()[0]); #region HttpCompletionOption //CompletionOption=requestMapping.CompletionOption.Value; iLGenerator.Emit(OpCodes.Dup); iLGenerator.EmitEnumValue(requestMapping.CompletionOption); iLGenerator.Emit(OpCodes.Callvirt, typeof(FeignClientHttpRequest).GetProperty("CompletionOption").SetMethod); #endregion iLGenerator.Emit(OpCodes.Stloc, localBuilder); return(localBuilder); #endregion }
public void BuildMethod(MethodInfo method, MethodBuilder methodBuilder, RequestMappingBaseAttribute requestMapping) { ILGenerator iLGenerator = methodBuilder.GetILGenerator(); if (requestMapping == null) { iLGenerator.Emit(OpCodes.Newobj, typeof(NotSupportedException).GetConstructor(Type.EmptyTypes)); iLGenerator.Emit(OpCodes.Throw); return; } string uri = requestMapping.Value ?? ""; LocalBuilder local_Uri = iLGenerator.DeclareLocal(typeof(string)); LocalBuilder local_OldValue = iLGenerator.DeclareLocal(typeof(string)); iLGenerator.Emit(OpCodes.Ldstr, uri); iLGenerator.Emit(OpCodes.Stloc, local_Uri); ParameterInfo requestBodyParameter = null; int requestBodyParameterIndex = -1; int index = 1; foreach (var parameterInfo in method.GetParameters()) { if (parameterInfo.IsDefined(typeof(RequestBodyAttribute))) { if (requestBodyParameter != null) { throw new ArgumentException("最多只能有一个RequestBody", parameterInfo.Name); } requestBodyParameter = parameterInfo; requestBodyParameterIndex = index; continue; } MethodInfo replaceValueMethod; string name; if (parameterInfo.IsDefined(typeof(RequestParamAttribute))) { name = parameterInfo.GetCustomAttribute <RequestParamAttribute>().Name ?? parameterInfo.Name; replaceValueMethod = _replaceRequestParamMethod; } else if (parameterInfo.IsDefined(typeof(RequestQueryAttribute))) { name = parameterInfo.Name; replaceValueMethod = _replaceRequestQueryMethod; } else { name = parameterInfo.IsDefined(typeof(PathVariableAttribute)) ? parameterInfo.GetCustomAttribute <PathVariableAttribute>().Name : parameterInfo.Name; replaceValueMethod = _replacePathVariableMethod; } if (string.IsNullOrWhiteSpace(name)) { name = parameterInfo.Name; } iLGenerator.Emit(OpCodes.Ldstr, name); iLGenerator.Emit(OpCodes.Stloc, local_OldValue); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldloc, local_Uri); iLGenerator.Emit(OpCodes.Ldloc, local_OldValue); iLGenerator.Emit(OpCodes.Ldarg_S, index); replaceValueMethod = replaceValueMethod.MakeGenericMethod(parameterInfo.ParameterType); iLGenerator.Emit(OpCodes.Call, replaceValueMethod); iLGenerator.Emit(OpCodes.Stloc, local_Uri); index++; } var invokeMethod = GetInvokeMethod(method, requestMapping); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldloc, local_Uri); if (NeedRequestBody(invokeMethod)) { if (requestBodyParameter != null) { iLGenerator.Emit(OpCodes.Ldarg_S, requestBodyParameterIndex); } else { iLGenerator.Emit(OpCodes.Ldnull); } } iLGenerator.Emit(OpCodes.Call, invokeMethod); if (method.ReturnType == null || method.ReturnType == typeof(void)) { LocalBuilder local_Result = iLGenerator.DeclareLocal(invokeMethod.ReturnType); iLGenerator.Emit(OpCodes.Stloc, local_Result); iLGenerator.Emit(OpCodes.Ldloc, local_Result); iLGenerator.Emit(OpCodes.Pop); } iLGenerator.Emit(OpCodes.Ret); }
protected bool SupportRequestContent(MethodInfo method, RequestMappingBaseAttribute requestMappingBaseAttribute) { return("POST".Equals(requestMappingBaseAttribute.GetMethod(), StringComparison.OrdinalIgnoreCase) || "PUT".Equals(requestMappingBaseAttribute.GetMethod(), StringComparison.OrdinalIgnoreCase)); }
/// <summary> /// 是否支持RequestContent /// </summary> /// <param name="method"></param> /// <param name="requestMappingBaseAttribute"></param> /// <returns></returns> protected bool SupportRequestContent(MethodInfo method, RequestMappingBaseAttribute requestMappingBaseAttribute) { return(requestMappingBaseAttribute.IsSupportRequestContent()); }
protected override void EmitCallMethod(TypeBuilder typeBuilder, MethodBuilder methodBuilder, ILGenerator iLGenerator, Type serviceType, FeignClientMethodInfo feignClientMethodInfo, RequestMappingBaseAttribute requestMapping, LocalBuilder uri, List <EmitRequestContent> emitRequestContents) { var invokeMethod = GetInvokeMethod(serviceType, feignClientMethodInfo.MethodMetadata, requestMapping); if (emitRequestContents != null && emitRequestContents.Count > 0 && !SupportRequestContent(invokeMethod, requestMapping)) { throw new NotSupportedException("不支持RequestBody或者RequestForm"); } LocalBuilder feignClientRequest = DefineFeignClientRequest(typeBuilder, serviceType, iLGenerator, uri, requestMapping, emitRequestContents, feignClientMethodInfo); // fallback LocalBuilder fallbackDelegate = DefineFallbackDelegate(typeBuilder, methodBuilder, iLGenerator, serviceType, feignClientMethodInfo.MethodMetadata); iLGenerator.Emit(OpCodes.Ldarg_0); //this iLGenerator.Emit(OpCodes.Ldloc, feignClientRequest); iLGenerator.Emit(OpCodes.Ldloc, fallbackDelegate); iLGenerator.Emit(OpCodes.Call, invokeMethod); iLGenerator.Emit(OpCodes.Ret); }
///// <summary> ///// 定义用于Send方法的FeignClientHttpRequest ///// </summary> ///// <param name="typeBuilder"></param> ///// <param name="serviceType"></param> ///// <param name="iLGenerator"></param> ///// <param name="uri"></param> ///// <param name="requestMapping"></param> ///// <param name="emitRequestContents"></param> ///// <param name="feignClientMethodInfo"></param> ///// <returns></returns> //protected LocalBuilder DefineFeignClientRequest_Old(TypeBuilder typeBuilder, Type serviceType, ILGenerator iLGenerator, LocalBuilder uri, RequestMappingBaseAttribute requestMapping, List<EmitRequestContent> emitRequestContents, FeignClientMethodInfo feignClientMethodInfo) //{ // LocalBuilder localBuilder = iLGenerator.DeclareLocal(typeof(FeignClientHttpRequest)); // // baseUrl // PropertyInfo propertyInfo = typeof(FeignClientHttpProxy<>).MakeGenericType(serviceType).GetProperty("BaseUrl", BindingFlags.Instance | BindingFlags.NonPublic); // iLGenerator.Emit(OpCodes.Ldarg_0); //this // iLGenerator.Emit(OpCodes.Callvirt, propertyInfo.GetMethod); // //mapping uri // if (requestMapping.Value == null) // { // iLGenerator.Emit(OpCodes.Ldnull); // } // else // { // iLGenerator.Emit(OpCodes.Ldstr, requestMapping.Value); // } // //uri // iLGenerator.Emit(OpCodes.Ldloc, uri); // //httpMethod // iLGenerator.Emit(OpCodes.Ldstr, requestMapping.GetMethod()); // //contentType // string contentType = requestMapping.ContentType; // if (string.IsNullOrWhiteSpace(contentType) && serviceType.IsDefined(typeof(RequestMappingAttribute))) // { // contentType = serviceType.GetCustomAttribute<RequestMappingAttribute>().ContentType; // } // if (contentType == null) // { // iLGenerator.Emit(OpCodes.Ldnull); // } // else // { // iLGenerator.Emit(OpCodes.Ldstr, contentType); // } // //accept // string accept = requestMapping.Accept; // if (string.IsNullOrWhiteSpace(contentType) && serviceType.IsDefined(typeof(RequestMappingAttribute))) // { // accept = serviceType.GetCustomAttribute<RequestMappingAttribute>().Accept; // } // if (accept == null) // { // iLGenerator.Emit(OpCodes.Ldnull); // } // else // { // iLGenerator.Emit(OpCodes.Ldstr, accept); // } // //headers // List<IEmitValue<string>> headers = new List<IEmitValue<string>>(); // if (serviceType.IsDefined(typeof(HeadersAttribute), true)) // { // var serviceHeaders = serviceType.GetCustomAttribute<HeadersAttribute>().Headers; // if (serviceHeaders != null) // { // headers.AddRange(serviceHeaders.Select(s => new EmitConstantStringValue(s))); // } // } // if (feignClientMethodInfo.MethodMetadata.IsDefined(typeof(HeadersAttribute), true)) // { // var methodHeaders = feignClientMethodInfo.MethodMetadata.GetCustomAttribute<HeadersAttribute>().Headers; // if (methodHeaders != null) // { // headers.AddRange(methodHeaders.Select(s => new EmitConstantStringValue(s))); // } // } // if (headers.Count == 0) // { // iLGenerator.Emit(OpCodes.Ldnull); // } // else // { // iLGenerator.EmitStringArray(headers); // } // //requestContent // if (emitRequestContents != null && emitRequestContents.Count > 0) // { // if (emitRequestContents.Count == 1) // { // if (typeof(IHttpRequestFile).IsAssignableFrom(emitRequestContents[0].Parameter.ParameterType)) // { // EmitFeignClientMultipartRequestContent(iLGenerator, emitRequestContents); // } // else // { // EmitFeignClientRequestContent(iLGenerator, emitRequestContents[0], null); // } // } // else if (emitRequestContents.Any(s => !s.SupportMultipart)) // { // throw new NotSupportedException("最多只支持一个RequestContent \r\n " + feignClientMethodInfo.ToString()); // } // else // { // EmitFeignClientMultipartRequestContent(iLGenerator, emitRequestContents); // } // } // else // { // iLGenerator.Emit(OpCodes.Ldnull); // } // #region new // //feignClientMethodInfo // //feignClientMethodInfo=null // LocalBuilder feignClientMethodInfoLocalBuilder = iLGenerator.DeclareLocal(typeof(FeignClientMethodInfo)); // iLGenerator.Emit(OpCodes.Newobj, typeof(FeignClientMethodInfo).GetEmptyConstructor()); // iLGenerator.Emit(OpCodes.Stloc, feignClientMethodInfoLocalBuilder); // iLGenerator.Emit(OpCodes.Ldloc, feignClientMethodInfoLocalBuilder); // iLGenerator.Emit(OpCodes.Ldstr, feignClientMethodInfo.MethodId); // iLGenerator.Emit(OpCodes.Call, typeof(FeignClientMethodInfo).GetProperty("MethodId").SetMethod); // #region ResultType // //feignClientMethodInfo.ResultType=typeof(xx); // ResultTypeAttribute resultTypeAttribute = feignClientMethodInfo.MethodMetadata.GetCustomAttribute<ResultTypeAttribute>(); // Type returnType = GetReturnType(feignClientMethodInfo.MethodMetadata); // if (returnType != null && resultTypeAttribute != null) // { // Type resultType = resultTypeAttribute.ConvertType(returnType); // if (resultType != null) // { // iLGenerator.Emit(OpCodes.Ldloc, feignClientMethodInfoLocalBuilder); // iLGenerator.EmitType(resultType); // iLGenerator.Emit(OpCodes.Call, typeof(FeignClientMethodInfo).GetProperty("ResultType").SetMethod); // } // } // #endregion // Label newFeingClientRequestLabel = iLGenerator.DefineLabel(); // #region if (base.FeignOptions.IncludeMethodMetadata) set the call method // //这里获取方法元数据 // PropertyInfo feignOptionsProperty = typeBuilder.BaseType.GetProperty("FeignOptions", BindingFlags.Instance | BindingFlags.NonPublic); // PropertyInfo includeMethodMetadataProperty = feignOptionsProperty.PropertyType.GetProperty("IncludeMethodMetadata"); // iLGenerator.Emit(OpCodes.Ldarg_0); // iLGenerator.Emit(OpCodes.Call, feignOptionsProperty.GetMethod); // iLGenerator.Emit(OpCodes.Callvirt, includeMethodMetadataProperty.GetMethod); // iLGenerator.Emit(OpCodes.Ldc_I4, 1); // iLGenerator.Emit(OpCodes.Ceq); // iLGenerator.Emit(OpCodes.Brfalse_S, newFeingClientRequestLabel); // iLGenerator.Emit(OpCodes.Ldloc, feignClientMethodInfoLocalBuilder); // iLGenerator.EmitMethodInfo(feignClientMethodInfo.MethodMetadata); // iLGenerator.Emit(OpCodes.Call, typeof(FeignClientMethodInfo).GetProperty("MethodMetadata").SetMethod); // #endregion // //处理下 if GOTO // iLGenerator.MarkLabel(newFeingClientRequestLabel); // iLGenerator.Emit(OpCodes.Ldloc, feignClientMethodInfoLocalBuilder); // iLGenerator.Emit(OpCodes.Newobj, typeof(FeignClientHttpRequest).GetFirstConstructor()); // #region HttpCompletionOption // //CompletionOption=requestMapping.CompletionOption.Value; // iLGenerator.Emit(OpCodes.Dup); // iLGenerator.EmitEnumValue(requestMapping.CompletionOption); // iLGenerator.Emit(OpCodes.Callvirt, typeof(FeignClientHttpRequest).GetProperty("CompletionOption").SetMethod); // #endregion // iLGenerator.Emit(OpCodes.Stloc, localBuilder); // //#region request headers // //// request headers // //List<Tuple<int, ParameterInfo, RequestHeaderBaseAttribute>> headerBaseAttributes = new List<Tuple<int, ParameterInfo, RequestHeaderBaseAttribute>>(); // //int parameterIndex = -1; // //foreach (var item in feignClientMethodInfo.MethodMetadata.GetParameters()) // //{ // // parameterIndex++; // // if (!item.IsDefined(typeof(RequestHeaderBaseAttribute))) // // { // // continue; // // } // // headerBaseAttributes.Add(Tuple.Create(parameterIndex, item, item.GetCustomAttribute<RequestHeaderBaseAttribute>())); // //} // //if (headerBaseAttributes.Count > 0) // //{ // // //feignClientHttpRequest.RequestHeaderHandlers = new List<IRequestHeaderHandler>(); // // iLGenerator.Emit(OpCodes.Ldloc, localBuilder); // // iLGenerator.Emit(OpCodes.Newobj, typeof(List<IRequestHeaderHandler>).GetEmptyConstructor()); // // iLGenerator.Emit(OpCodes.Callvirt, typeof(FeignClientHttpRequest).GetProperty("RequestHeaderHandlers").SetMethod); // // MethodInfo listAddItemMethodInfo = typeof(List<IRequestHeaderHandler>).GetMethod("Add"); // // foreach (var headerBaseAttribute in headerBaseAttributes) // // { // // //string text2 = "xxx"; // // //feignClientHttpRequest.RequestHeaderHandlers.Add(new RequestHeaderHandler("xxx", text2)); // // var valueBuilder = iLGenerator.DeclareLocal(typeof(string)); // // if (headerBaseAttribute.Item2.ParameterType == typeof(string)) // // { // // iLGenerator.Emit(OpCodes.Ldarg_S, headerBaseAttribute.Item1 + 1); // // } // // else // // { // // iLGenerator.Emit(OpCodes.Ldstr, "test"); // // } // // iLGenerator.Emit(OpCodes.Stloc, valueBuilder); // // var handlerLocalBuilder = headerBaseAttribute.Item3.EmitNewRequestHeaderHandler(iLGenerator, valueBuilder); // // if (handlerLocalBuilder!=null) // // { // // iLGenerator.Emit(OpCodes.Ldloc, localBuilder); // // iLGenerator.Emit(OpCodes.Callvirt, typeof(FeignClientHttpRequest).GetProperty("RequestHeaderHandlers").GetMethod); // // iLGenerator.Emit(OpCodes.Callvirt, listAddItemMethodInfo); // // } // // } // //} // //#endregion // return localBuilder; // #endregion //} #endregion /// <summary> /// 定义用于Send方法的FeignClientHttpRequest /// </summary> /// <param name="typeBuilder"></param> /// <param name="serviceType"></param> /// <param name="iLGenerator"></param> /// <param name="uri"></param> /// <param name="requestMapping"></param> /// <param name="emitRequestContents"></param> /// <param name="feignClientMethodInfo"></param> /// <returns></returns> protected LocalBuilder DefineFeignClientRequest(TypeBuilder typeBuilder, Type serviceType, ILGenerator iLGenerator, LocalBuilder uri, RequestMappingBaseAttribute requestMapping, List <EmitRequestContent> emitRequestContents, FeignClientMethodInfo feignClientMethodInfo) { LocalBuilder localBuilder = iLGenerator.DeclareLocal(typeof(FeignClientHttpRequest)); #region localBuilder = new FeignClientHttpRequest(string baseUrl, string mappingUri, string uri, string httpMethod, string contentType) // baseUrl iLGenerator.Emit(OpCodes.Ldarg_0); //this iLGenerator.Emit(OpCodes.Callvirt, typeof(FeignClientHttpProxy <>).MakeGenericType(serviceType).GetProperty("BaseUrl", BindingFlags.Instance | BindingFlags.NonPublic).GetMethod); //mapping uri if (requestMapping.Value == null) { iLGenerator.Emit(OpCodes.Ldnull); } else { iLGenerator.Emit(OpCodes.Ldstr, requestMapping.Value); } //uri iLGenerator.Emit(OpCodes.Ldloc, uri); //httpMethod iLGenerator.Emit(OpCodes.Ldstr, requestMapping.GetMethod()); //contentType string contentType = requestMapping.ContentType; if (string.IsNullOrWhiteSpace(contentType) && serviceType.IsDefined(typeof(RequestMappingAttribute))) { contentType = serviceType.GetCustomAttribute <RequestMappingAttribute>().ContentType; } if (contentType == null) { iLGenerator.Emit(OpCodes.Ldnull); } else { iLGenerator.Emit(OpCodes.Ldstr, contentType); } //new FeignClientHttpRequest(baseUrl, mappingUri, uri, httpMethod, contentType) iLGenerator.Emit(OpCodes.Newobj, typeof(FeignClientHttpRequest).GetFirstConstructor()); #region HttpCompletionOption //CompletionOption=requestMapping.CompletionOption.Value; iLGenerator.Emit(OpCodes.Dup); iLGenerator.EmitEnumValue(requestMapping.CompletionOption); iLGenerator.Emit(OpCodes.Callvirt, typeof(FeignClientHttpRequest).GetProperty("CompletionOption").SetMethod); #endregion iLGenerator.Emit(OpCodes.Stloc, localBuilder); #endregion #region FeignClientHttpRequest.Method //feignClientMethodInfo //feignClientMethodInfo=null LocalBuilder feignClientMethodInfoLocalBuilder = iLGenerator.DeclareLocal(typeof(FeignClientMethodInfo)); iLGenerator.Emit(OpCodes.Newobj, typeof(FeignClientMethodInfo).GetEmptyConstructor()); iLGenerator.Emit(OpCodes.Stloc, feignClientMethodInfoLocalBuilder); iLGenerator.Emit(OpCodes.Ldloc, feignClientMethodInfoLocalBuilder); iLGenerator.Emit(OpCodes.Ldstr, feignClientMethodInfo.MethodId); iLGenerator.Emit(OpCodes.Call, typeof(FeignClientMethodInfo).GetProperty("MethodId").SetMethod); #region ResultType //feignClientMethodInfo.ResultType=typeof(xx); ResultTypeAttribute resultTypeAttribute = feignClientMethodInfo.MethodMetadata.GetCustomAttribute <ResultTypeAttribute>(); Type returnType = GetReturnType(feignClientMethodInfo.MethodMetadata); if (returnType != null && resultTypeAttribute != null) { Type resultType = resultTypeAttribute.ConvertType(returnType); if (resultType != null) { iLGenerator.Emit(OpCodes.Ldloc, feignClientMethodInfoLocalBuilder); iLGenerator.EmitType(resultType); iLGenerator.Emit(OpCodes.Call, typeof(FeignClientMethodInfo).GetProperty("ResultType").SetMethod); } } #endregion Label newFeingClientRequestLabel = iLGenerator.DefineLabel(); #region if (base.FeignOptions.IncludeMethodMetadata) set the call method //这里获取方法元数据 PropertyInfo feignOptionsProperty = typeBuilder.BaseType.GetProperty("FeignOptions", BindingFlags.Instance | BindingFlags.NonPublic); PropertyInfo includeMethodMetadataProperty = feignOptionsProperty.PropertyType.GetProperty("IncludeMethodMetadata"); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Call, feignOptionsProperty.GetMethod); iLGenerator.Emit(OpCodes.Callvirt, includeMethodMetadataProperty.GetMethod); iLGenerator.Emit(OpCodes.Ldc_I4, 1); iLGenerator.Emit(OpCodes.Ceq); iLGenerator.Emit(OpCodes.Brfalse_S, newFeingClientRequestLabel); iLGenerator.Emit(OpCodes.Ldloc, feignClientMethodInfoLocalBuilder); iLGenerator.EmitMethodInfo(feignClientMethodInfo.MethodMetadata); iLGenerator.Emit(OpCodes.Call, typeof(FeignClientMethodInfo).GetProperty("MethodMetadata").SetMethod); #endregion //处理下 if GOTO iLGenerator.MarkLabel(newFeingClientRequestLabel); iLGenerator.Emit(OpCodes.Ldloc, localBuilder); iLGenerator.Emit(OpCodes.Ldloc, feignClientMethodInfoLocalBuilder); iLGenerator.Emit(OpCodes.Call, typeof(FeignClientHttpRequest).GetProperty("Method").SetMethod); #endregion #region FeignClientHttpRequest.Accept //accept string accept = requestMapping.Accept; if (string.IsNullOrWhiteSpace(accept) && serviceType.IsDefined(typeof(RequestMappingAttribute))) { accept = serviceType.GetCustomAttribute <RequestMappingAttribute>().Accept; } if (accept != null) { iLGenerator.Emit(OpCodes.Ldloc, localBuilder); iLGenerator.Emit(OpCodes.Ldstr, accept); iLGenerator.Emit(OpCodes.Call, typeof(FeignClientHttpRequest).GetProperty("Accept").SetMethod); } #endregion #region FeignClientHttpRequest.Headers //headers List <IEmitValue <string> > headers = new List <IEmitValue <string> >(); if (serviceType.IsDefined(typeof(HeadersAttribute), true)) { var serviceHeaders = serviceType.GetCustomAttribute <HeadersAttribute>().Headers; if (serviceHeaders != null) { headers.AddRange(serviceHeaders.Select(s => new EmitConstantStringValue(s))); } } if (feignClientMethodInfo.MethodMetadata.IsDefined(typeof(HeadersAttribute), true)) { var methodHeaders = feignClientMethodInfo.MethodMetadata.GetCustomAttribute <HeadersAttribute>().Headers; if (methodHeaders != null) { headers.AddRange(methodHeaders.Select(s => new EmitConstantStringValue(s))); } } if (headers.Count >= 0) { iLGenerator.Emit(OpCodes.Ldloc, localBuilder); iLGenerator.EmitStringArray(headers); iLGenerator.Emit(OpCodes.Call, typeof(FeignClientHttpRequest).GetProperty("Headers").SetMethod); } #endregion #region FeignClientHttpRequest.RequestContent //requestContent if (emitRequestContents != null && emitRequestContents.Count > 0) { iLGenerator.Emit(OpCodes.Ldloc, localBuilder); if (emitRequestContents.Count == 1) { if (typeof(IHttpRequestFile).IsAssignableFrom(emitRequestContents[0].Parameter.ParameterType)) { EmitFeignClientMultipartRequestContent(iLGenerator, emitRequestContents); } else { EmitFeignClientRequestContent(iLGenerator, emitRequestContents[0], null); } } else if (emitRequestContents.Any(s => !s.SupportMultipart)) { throw new NotSupportedException("最多只支持一个RequestContent \r\n " + feignClientMethodInfo.ToString()); } else { EmitFeignClientMultipartRequestContent(iLGenerator, emitRequestContents); } iLGenerator.Emit(OpCodes.Call, typeof(FeignClientHttpRequest).GetProperty("RequestContent").SetMethod); } #endregion #region FeignClientHttpRequest.RequestHeaderHandlers // request headers List <Tuple <int, ParameterInfo, RequestHeaderBaseAttribute> > headerBaseAttributes = new List <Tuple <int, ParameterInfo, RequestHeaderBaseAttribute> >(); int parameterIndex = -1; foreach (var item in feignClientMethodInfo.MethodMetadata.GetParameters()) { parameterIndex++; if (!item.IsDefined(typeof(RequestHeaderBaseAttribute))) { continue; } headerBaseAttributes.Add(Tuple.Create(parameterIndex, item, item.GetCustomAttribute <RequestHeaderBaseAttribute>())); } if (headerBaseAttributes.Count > 0) { //feignClientHttpRequest.RequestHeaderHandlers = new List<IRequestHeaderHandler>(); iLGenerator.Emit(OpCodes.Ldloc, localBuilder); iLGenerator.Emit(OpCodes.Newobj, typeof(List <IRequestHeaderHandler>).GetEmptyConstructor()); iLGenerator.Emit(OpCodes.Callvirt, typeof(FeignClientHttpRequest).GetProperty("RequestHeaderHandlers").SetMethod); MethodInfo listAddItemMethodInfo = typeof(List <IRequestHeaderHandler>).GetMethod("Add"); foreach (var headerBaseAttribute in headerBaseAttributes) { //string text2 = "xxx"; //feignClientHttpRequest.RequestHeaderHandlers.Add(new RequestHeaderHandler("xxx", text2)); var valueBuilder = iLGenerator.DeclareLocal(typeof(string)); iLGenerator.Emit(OpCodes.Ldarg_S, headerBaseAttribute.Item1 + 1); if (headerBaseAttribute.Item2.ParameterType != typeof(string)) { iLGenerator.Emit(OpCodes.Call, GetConvertToStringValueMethod(typeBuilder, headerBaseAttribute.Item2.ParameterType)); } iLGenerator.Emit(OpCodes.Stloc, valueBuilder); var handlerLocalBuilder = headerBaseAttribute.Item3.EmitNewRequestHeaderHandler(iLGenerator, valueBuilder); if (handlerLocalBuilder != null) { iLGenerator.Emit(OpCodes.Ldloc, localBuilder); iLGenerator.Emit(OpCodes.Callvirt, typeof(FeignClientHttpRequest).GetProperty("RequestHeaderHandlers").GetMethod); iLGenerator.Emit(OpCodes.Ldloc, handlerLocalBuilder); iLGenerator.Emit(OpCodes.Callvirt, listAddItemMethodInfo); } } } #endregion return(localBuilder); }