private static Type GetNatsClientRequestType(int count) { lock (_syncLock) { if (_requestTypes.TryGetValue(count, out var type)) { return(type); } var typeBuilder = NatsClientAssembly.DefineClassType("NatsClientRequest" + count); typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(DataContractAttribute).GetConstructor(Type.EmptyTypes), Array.Empty <object>())); var types = typeBuilder.DefineGenericParameters(Enumerable.Range(1, count).Select(x => $"TP{x}").ToArray()); var fields = BuildProperties(typeBuilder, types); var defaultConstructor = typeBuilder.DefineDefaultConstructor(MethodAttributes.Public); var constructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, types); var il = constructor.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, defaultConstructor); for (var i = 0; i < count; i++) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg, i + 1); il.Emit(OpCodes.Stfld, fields[i]); } il.Emit(OpCodes.Ret); return(_requestTypes[count] = typeBuilder.CreateType()); } }
static NatsClientGenerator() { if (!typeof(TContract).IsInterface) { throw new Exception("TContract must be an interface"); } var typeBuilder = NatsClientAssembly.DefineClassType($"{typeof(TContract).Name}Client"); typeBuilder.AddInterfaceImplementation(typeof(TContract)); typeBuilder.SetParent(typeof(NatsClientProxy)); CreateConstructor(typeBuilder); CreateMethods(typeBuilder); _type = typeBuilder.CreateType(); }