예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }