public Type BuildType(Type serviceType) { if (!NeedBuildType(serviceType)) { return(null); } Type interfaceType = serviceType; FeignClientAttribute feignClientAttribute = interfaceType.GetCustomAttribute <FeignClientAttribute>(); IMethodBuilder methodBuilder; Type parentType; if (feignClientAttribute.Fallback != null) { methodBuilder = _fallbackMethodBuilder; parentType = typeof(FallbackFeignClientHttpProxy <,>); parentType = parentType.MakeGenericType(interfaceType, feignClientAttribute.Fallback); } else if (feignClientAttribute.FallbackFactory != null) { methodBuilder = _fallbackMethodBuilder; parentType = typeof(FallbackFactoryFeignClientHttpProxy <,>); parentType = parentType.MakeGenericType(interfaceType, feignClientAttribute.FallbackFactory); } else { methodBuilder = _methodBuilder; parentType = typeof(FeignClientHttpProxy <>); parentType = parentType.MakeGenericType(interfaceType); } parentType = GetParentType(parentType); TypeBuilder typeBuilder = CreateTypeBuilder(GetTypeFullName(interfaceType), parentType); BuildConstructor(typeBuilder, parentType); BuildServiceIdProperty(typeBuilder, interfaceType); BuildBaseUriProperty(typeBuilder, interfaceType); BuildUrlProperty(typeBuilder, interfaceType); typeBuilder.AddInterfaceImplementation(interfaceType); foreach (var method in interfaceType.GetMethods()) { methodBuilder.BuildMethod(typeBuilder, interfaceType, method, feignClientAttribute); } var typeInfo = typeBuilder.CreateTypeInfo(); Type type = typeInfo.AsType(); return(type); }
public FeignClientTypeInfo Build(Type serviceType) { //校验一下是否可以生成代理类型 if (!NeedBuildType(serviceType)) { return(null); } //获取一下描述特性 FeignClientAttribute feignClientAttribute = serviceType.GetCustomAttributeIncludingBaseInterfaces <FeignClientAttribute>(); IMethodBuilder methodBuilder; Type parentType; if (feignClientAttribute.Fallback != null) { //此服务支持服务降级 methodBuilder = _fallbackMethodBuilder; parentType = typeof(FallbackFeignClientHttpProxy <,>); parentType = parentType.MakeGenericType(serviceType, feignClientAttribute.Fallback); } else if (feignClientAttribute.FallbackFactory != null) { //此服务支持服务降级(降级服务由factory提供) methodBuilder = _fallbackMethodBuilder; parentType = typeof(FallbackFactoryFeignClientHttpProxy <,>); parentType = parentType.MakeGenericType(serviceType, feignClientAttribute.FallbackFactory); } else { //默认的服务 methodBuilder = _methodBuilder; parentType = typeof(FeignClientHttpProxy <>); parentType = parentType.MakeGenericType(serviceType); } parentType = GetParentType(parentType); FeignClientTypeInfo feignClientTypeInfo = new FeignClientTypeInfo(serviceType) { ParentType = parentType }; //创建类型 TypeAttributes typeAttributes = TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout; TypeBuilder typeBuilder = _dynamicAssembly.DefineType(GetTypeFullName(serviceType), typeAttributes, parentType, new Type[] { serviceType }); //写入构造函数 typeBuilder.BuildFirstConstructor(parentType); //写入serviceId typeBuilder.DefineReadOnlyProperty(serviceType, "ServiceId", feignClientAttribute.Name); //写入baseUri typeBuilder.DefineReadOnlyProperty(serviceType, "BaseUri", serviceType.GetCustomAttribute <RequestMappingAttribute>()?.Value); // 写入url if (feignClientAttribute.Url != null) { typeBuilder.DefineReadOnlyProperty(serviceType, "Url", feignClientAttribute.Url); } foreach (var method in serviceType.GetMethodsIncludingBaseInterfaces()) { //生成方法 var buildMethod = methodBuilder.BuildMethod(typeBuilder, serviceType, method, feignClientAttribute); feignClientTypeInfo.Methods.Add(buildMethod); } foreach (var property in serviceType.GetPropertiesIncludingBaseInterfaces()) { //写入自动属性 //typeBuilder.DefineAutoProperty(serviceType, property); typeBuilder.DefineExplicitAutoProperty(serviceType, property); } var typeInfo = typeBuilder.CreateTypeInfo(); Type type = typeInfo.AsType(); feignClientTypeInfo.BuildType = type; return(feignClientTypeInfo); }
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); }
public void BuildMethod(TypeBuilder typeBuilder, Type serviceType, MethodInfo method, FeignClientAttribute feignClientAttribute) { BuildMethod(typeBuilder, serviceType, method, feignClientAttribute, GetRequestMappingAttribute(method)); }
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); }