public static TInterface CreateProxy <TInterface>(Type channelType, Type ctorArgType, object channelCtorValue) where TInterface : class { if (!channelType.InheritsFrom(typeof(Channel))) { throw new ArgumentException("channelType does not inherit from Channel"); } 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); }
private static TInterface CreateProxy <TInterface>(ProxyBuilder proxyBuilder, object channelCtorValue) where TInterface : class { //create the type and construct an instance Type[] ctorArgTypes = new Type[] { typeof(Type), proxyBuilder.CtorType }; Type t = proxyBuilder.TypeBuilder.CreateType(); var constructorInfo = t.GetConstructor(ctorArgTypes); if (constructorInfo != null) { TInterface 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 AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(PROXY_ASSEMBLY), AssemblyBuilderAccess.Run); // create a new module for the proxy ModuleBuilder 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 TypeBuilder typeBuilder = moduleBuilder.DefineType(interfaceType.Name + PROXY, typeAttributes, channelType); List <Type> allInterfaces = new List <Type>(interfaceType.GetInterfaces()); allInterfaces.Add(interfaceType); //add the interface typeBuilder.AddInterfaceImplementation(interfaceType); //construct the constructor Type[] ctorArgTypes = new Type[] { typeof(Type), ctorArgType }; CreateConstructor(channelType, typeBuilder, ctorArgTypes); //construct the type maps Dictionary <Type, OpCode> 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); Dictionary <Type, OpCode> 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 List <MethodInfo> methods = GetAllMethods(allInterfaces); foreach (MethodInfo methodInfo in methods) { MethodBuilder 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); }