static void ImplementInterface(Type interfaceType, TypeBuilder builder, FieldBuilder channel) { if (builder.FindInterfaces((t, o) => t == interfaceType, null).Length == 0) { builder.AddInterfaceImplementation(interfaceType); var parentInterfaces = interfaceType.GetInterfaces(); foreach (var _interface in parentInterfaces) { ImplementInterface(_interface, builder, channel); } IEnumerable <MethodOperation> operations = null; var intInfo = interfaceType.GetTypeInfo(); if (ContractHelper.IsContract(intInfo)) { operations = ContractHelper.ValidateContract(intInfo); } else { operations = interfaceType.GetMethods().Select(x => new MethodOperation(x)); } foreach (var operation in operations) { var mb = builder.DefineMethod( $"{interfaceType.Name}.{operation.Name}", MethodAttributes.Public | MethodAttributes.Virtual, operation.ReturnType, operation.Parameters); var il = mb.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, channel); MethodInfo invoke = null; //implement the user interface if (operation.IsOperation) { if (operation.IsOneWay) { invoke = ImplementingType.GetMethod("SendOneWay"); } else if (operation.IsVoidTask) { invoke = ImplementingType.GetMethod("SendVoid"); } else { invoke = ImplementingType.GetMethod("SendReturn") .MakeGenericMethod(operation.ReturnType.GetGenericArguments() .First()); } il.Emit(OpCodes.Ldstr, mb.Name); il.Emit(OpCodes.Ldc_I4_S, operation.Parameters.Length); il.Emit(OpCodes.Newarr, typeof(object)); for (byte x = 0; x < operation.Parameters.Length; x++) { il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldc_I4_S, x); switch (x) { case 0: il.Emit(OpCodes.Ldarg_1); break; case 1: il.Emit(OpCodes.Ldarg_2); break; case 2: il.Emit(OpCodes.Ldarg_3); break; default: il.Emit(OpCodes.Ldarg_S); break; } il.Emit(OpCodes.Stelem_Ref); } } else { invoke = ImplementingType.GetMethod(operation.Name, operation.Parameters); for (byte x = 0; x < operation.Parameters.Length; x++) { switch (x) { case 0: il.Emit(OpCodes.Ldarg_1, x); break; case 1: il.Emit(OpCodes.Ldarg_2, x); break; case 2: il.Emit(OpCodes.Ldarg_3, x); break; default: il.Emit(OpCodes.Ldarg_S, x); break; } } } il.Emit(OpCodes.Call, invoke); il.Emit(OpCodes.Ret); builder.DefineMethodOverride(mb, operation.MethodInfo); } } }