LocalBuilder DefineFallbackDelegate(TypeBuilder typeBuilder, MethodBuilder methodBuilder, ILGenerator iLGenerator, Type serviceType, MethodInfo method) { Type delegateType; if (method.ReturnType == null || method.ReturnType == typeof(void)) { delegateType = typeof(Action); } else { delegateType = typeof(Func <>).MakeGenericType(method.ReturnType); } int bindingFlagsValue = 0; foreach (BindingFlags item in Enum.GetValues(typeof(BindingFlags))) { bindingFlagsValue += item.GetHashCode(); } var delegateConstructor = delegateType.GetConstructors((BindingFlags)bindingFlagsValue)[0]; LocalBuilder invokeDelegate = iLGenerator.DeclareLocal(delegateType); // if has parameters if (method.GetParameters().Length > 0) { var anonymousMethodClassTypeBuild = FallbackProxyAnonymousMethodClassBuilder.BuildType(_dynamicAssembly.ModuleBuilder, serviceType, method); // new anonymousMethodClass LocalBuilder anonymousMethodClass = iLGenerator.DeclareLocal(anonymousMethodClassTypeBuild.Item1); //field iLGenerator.Emit(OpCodes.Ldarg_0); //this iLGenerator.Emit(OpCodes.Call, typeBuilder.BaseType.GetProperty("Fallback").GetMethod); //.Fallback for (int i = 1; i <= method.GetParameters().Length; i++) { iLGenerator.Emit(OpCodes.Ldarg_S, i); } iLGenerator.Emit(OpCodes.Newobj, anonymousMethodClassTypeBuild.Item2); iLGenerator.Emit(OpCodes.Stloc, anonymousMethodClass); iLGenerator.Emit(OpCodes.Ldloc, anonymousMethodClass); iLGenerator.Emit(OpCodes.Ldftn, anonymousMethodClassTypeBuild.Item3); } else { iLGenerator.Emit(OpCodes.Ldarg_0); //this iLGenerator.Emit(OpCodes.Call, typeBuilder.BaseType.GetProperty("Fallback").GetMethod); //.Fallback iLGenerator.Emit(OpCodes.Ldftn, method); } iLGenerator.Emit(OpCodes.Newobj, delegateConstructor); iLGenerator.Emit(OpCodes.Stloc, invokeDelegate); return(invokeDelegate); }
public FallbackFeignClientHttpProxyEmitMethodBuilder(DynamicAssembly dynamicAssembly) { _dynamicAssembly = dynamicAssembly; _fallbackProxyAnonymousMethodClassBuilder = new FallbackProxyAnonymousMethodClassBuilder(); }