Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }