public static TInterface CreateProxy <TInterface>(Type channelType, Type ctorArgType, object channelCtorValue) where TInterface : class { Type interfaceType = typeof(TInterface); // derive unique key for this dynamic assembly by interface, channel and ctor type names var proxyName = interfaceType.FullName + channelType.FullName + ctorArgType.FullName; // get pooled proxy builder var localChannelType = channelType; var localCtorArgType = ctorArgType; ProxyBuilder proxyBuilder = null; TInterface proxy = null; try { proxyBuilder = _proxies.Request(proxyName, () => CreateProxyBuilder(proxyName, interfaceType, localChannelType, localCtorArgType)); proxy = CreateProxy <TInterface>(proxyBuilder, channelCtorValue); } finally { // return builder to the pool if (null != proxyBuilder) { _proxies.Release(proxyName, proxyBuilder); } } return(proxy); }
public static TInterface CreateEmptyProxy <TInterface>(DynamicMethodBinder methodBinder, Type binderType, Type ctorArgType, object ctorArg) where TInterface : class { Type interfaceType = typeof(TInterface); // derive unique key for this dynamic assembly by interface, channel and ctor type names var proxyName = $"{PROXY}_" + interfaceType.FullName + binderType?.FullName + $"_{Guid.NewGuid().ToString("N")}"; // get pooled proxy builder ProxyBuilder proxyBuilder = null; TInterface proxy = null; try { proxyBuilder = _proxies.Request(proxyName, () => CreateSimpleProxyBuilder(proxyName, interfaceType, methodBinder, binderType, ctorArgType)); proxy = CreateEmptyProxy <TInterface>(proxyBuilder, ctorArg); } finally { // return builder to the pool if (null != proxyBuilder) { _proxies.Release(proxyName, proxyBuilder); } } return(proxy); }
private static TInterface CreateProxy <TInterface>(ProxyBuilder proxyBuilder, object channelCtorValue) where TInterface : class { //create the type and construct an instance Type[] ctorArgTypes = { typeof(Type), proxyBuilder.CtorType }; var tInfo = proxyBuilder.TypeBuilder.CreateTypeInfo(); var t = tInfo.AsType(); var constructorInfo = t.GetConstructor(ctorArgTypes); if (constructorInfo != null) { var instance = (TInterface)constructorInfo.Invoke(new object[] { typeof(TInterface), channelCtorValue }); return(instance); } return(null); }
private static ProxyBuilder CreateProxyBuilder(string proxyName, Type interfaceType, Type channelType, Type ctorArgType) { #if NETSTANDARD1_6 // create a new assembly for the proxy var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(PROXY_ASSEMBLY), AssemblyBuilderAccess.Run); // create a new module for the proxy var moduleBuilder = assemblyBuilder.DefineDynamicModule(PROXY_MODULE); #else AppDomain domain = Thread.GetDomain(); // create a new assembly for the proxy AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(new AssemblyName(PROXY_ASSEMBLY), AssemblyBuilderAccess.Run); // create a new module for the proxy ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(PROXY_MODULE, true); #endif // Set the class to be public and sealed TypeAttributes typeAttributes = TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed; // Construct the type builder var typeBuilder = moduleBuilder.DefineType(interfaceType.Name + PROXY, typeAttributes, channelType); var allInterfaces = new List <Type>(interfaceType.GetInterfaces()); allInterfaces.Add(interfaceType); // add the interface typeBuilder.AddInterfaceImplementation(interfaceType); // construct the constructor Type[] ctorArgTypes = { typeof(Type), ctorArgType }; CreateParameterizedConstructor(channelType, typeBuilder, ctorArgTypes); // construct the type maps var ldindOpCodeTypeMap = new Dictionary <Type, OpCode>(); ldindOpCodeTypeMap.Add(typeof(Boolean), OpCodes.Ldind_I1); ldindOpCodeTypeMap.Add(typeof(Byte), OpCodes.Ldind_U1); ldindOpCodeTypeMap.Add(typeof(SByte), OpCodes.Ldind_I1); ldindOpCodeTypeMap.Add(typeof(Int16), OpCodes.Ldind_I2); ldindOpCodeTypeMap.Add(typeof(UInt16), OpCodes.Ldind_U2); ldindOpCodeTypeMap.Add(typeof(Int32), OpCodes.Ldind_I4); ldindOpCodeTypeMap.Add(typeof(UInt32), OpCodes.Ldind_U4); ldindOpCodeTypeMap.Add(typeof(Int64), OpCodes.Ldind_I8); ldindOpCodeTypeMap.Add(typeof(UInt64), OpCodes.Ldind_I8); ldindOpCodeTypeMap.Add(typeof(Char), OpCodes.Ldind_U2); ldindOpCodeTypeMap.Add(typeof(Double), OpCodes.Ldind_R8); ldindOpCodeTypeMap.Add(typeof(Single), OpCodes.Ldind_R4); var stindOpCodeTypeMap = new Dictionary <Type, OpCode>(); stindOpCodeTypeMap.Add(typeof(Boolean), OpCodes.Stind_I1); stindOpCodeTypeMap.Add(typeof(Byte), OpCodes.Stind_I1); stindOpCodeTypeMap.Add(typeof(SByte), OpCodes.Stind_I1); stindOpCodeTypeMap.Add(typeof(Int16), OpCodes.Stind_I2); stindOpCodeTypeMap.Add(typeof(UInt16), OpCodes.Stind_I2); stindOpCodeTypeMap.Add(typeof(Int32), OpCodes.Stind_I4); stindOpCodeTypeMap.Add(typeof(UInt32), OpCodes.Stind_I4); stindOpCodeTypeMap.Add(typeof(Int64), OpCodes.Stind_I8); stindOpCodeTypeMap.Add(typeof(UInt64), OpCodes.Stind_I8); stindOpCodeTypeMap.Add(typeof(Char), OpCodes.Stind_I2); stindOpCodeTypeMap.Add(typeof(Double), OpCodes.Stind_R8); stindOpCodeTypeMap.Add(typeof(Single), OpCodes.Stind_R4); // construct the method builders from the method infos defined in the interface var methods = GetAllMethods(allInterfaces); foreach (MethodInfo methodInfo in methods) { var methodBuilder = ConstructMethod(channelType, methodInfo, typeBuilder, ldindOpCodeTypeMap, stindOpCodeTypeMap); typeBuilder.DefineMethodOverride(methodBuilder, methodInfo); } // create proxy builder var result = new ProxyBuilder { ProxyName = proxyName, InterfaceType = interfaceType, CtorType = ctorArgType, AssemblyBuilder = assemblyBuilder, ModuleBuilder = moduleBuilder, TypeBuilder = typeBuilder }; return(result); }
private static ProxyBuilder CreateSimpleProxyBuilder(string proxyName, Type interfaceType, DynamicMethodBinder methodBinder, Type parentType, Type ctorArgType = null) { // create a new assembly for the proxy var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(PROXY_ASSEMBLY), AssemblyBuilderAccess.Run); // create a new module for the proxy var moduleBuilder = assemblyBuilder.DefineDynamicModule(PROXY_MODULE); // Set the class to be public and sealed TypeAttributes typeAttributes = TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed; // Construct the type builder TypeBuilder typeBuilder; var genTypeName = $"{PROXY}_" + interfaceType.FullName + parentType?.FullName + $"_{Guid.NewGuid().ToString("N")}_{PROXY}"; if (parentType != null) { typeBuilder = moduleBuilder.DefineType(genTypeName, typeAttributes, parentType); } else { typeBuilder = moduleBuilder.DefineType(genTypeName, typeAttributes); } var allInterfaces = new List <Type>(interfaceType.GetInterfaces()); allInterfaces.Add(interfaceType); // add the interface typeBuilder.AddInterfaceImplementation(interfaceType); // construct the constructor // TODO Type[] ctorArgTypes = { ctorArgType }; CreateParameterizedConstructor(parentType, typeBuilder, ctorArgTypes); // construct the type maps var ldindOpCodeTypeMap = new Dictionary <Type, OpCode>(); ldindOpCodeTypeMap.Add(typeof(Boolean), OpCodes.Ldind_I1); ldindOpCodeTypeMap.Add(typeof(Byte), OpCodes.Ldind_U1); ldindOpCodeTypeMap.Add(typeof(SByte), OpCodes.Ldind_I1); ldindOpCodeTypeMap.Add(typeof(Int16), OpCodes.Ldind_I2); ldindOpCodeTypeMap.Add(typeof(UInt16), OpCodes.Ldind_U2); ldindOpCodeTypeMap.Add(typeof(Int32), OpCodes.Ldind_I4); ldindOpCodeTypeMap.Add(typeof(UInt32), OpCodes.Ldind_U4); ldindOpCodeTypeMap.Add(typeof(Int64), OpCodes.Ldind_I8); ldindOpCodeTypeMap.Add(typeof(UInt64), OpCodes.Ldind_I8); ldindOpCodeTypeMap.Add(typeof(Char), OpCodes.Ldind_U2); ldindOpCodeTypeMap.Add(typeof(Double), OpCodes.Ldind_R8); ldindOpCodeTypeMap.Add(typeof(Single), OpCodes.Ldind_R4); var stindOpCodeTypeMap = new Dictionary <Type, OpCode>(); stindOpCodeTypeMap.Add(typeof(Boolean), OpCodes.Stind_I1); stindOpCodeTypeMap.Add(typeof(Byte), OpCodes.Stind_I1); stindOpCodeTypeMap.Add(typeof(SByte), OpCodes.Stind_I1); stindOpCodeTypeMap.Add(typeof(Int16), OpCodes.Stind_I2); stindOpCodeTypeMap.Add(typeof(UInt16), OpCodes.Stind_I2); stindOpCodeTypeMap.Add(typeof(Int32), OpCodes.Stind_I4); stindOpCodeTypeMap.Add(typeof(UInt32), OpCodes.Stind_I4); stindOpCodeTypeMap.Add(typeof(Int64), OpCodes.Stind_I8); stindOpCodeTypeMap.Add(typeof(UInt64), OpCodes.Stind_I8); stindOpCodeTypeMap.Add(typeof(Char), OpCodes.Stind_I2); stindOpCodeTypeMap.Add(typeof(Double), OpCodes.Stind_R8); stindOpCodeTypeMap.Add(typeof(Single), OpCodes.Stind_R4); // TODO: Allow passing in a binder to handle method calls // construct the method builders from the method infos defined in the interface var methods = GetAllMethods(allInterfaces); foreach (MethodInfo methodInfo in methods) { var methodBuilder = BindMethod(methodBinder, methodInfo, typeBuilder, ldindOpCodeTypeMap, stindOpCodeTypeMap); typeBuilder.DefineMethodOverride(methodBuilder, methodInfo); } // create proxy builder var result = new ProxyBuilder { ProxyName = proxyName, InterfaceType = interfaceType, CtorType = ctorArgType, AssemblyBuilder = assemblyBuilder, ModuleBuilder = moduleBuilder, TypeBuilder = typeBuilder }; return(result); }