Exemple #1
0
        /// <summary>
        /// Creates an un-cached proxy class.
        /// </summary>
        /// <param name="baseType">
        /// The base <see cref="Type"/> to proxy.
        /// </param>
        /// <returns>
        /// The proxy <see cref="Type"/>.
        /// </returns>
        private Type CreateUncachedProxyType(Type baseType)
        {
            // Create a dynamic assembly and module to store the proxy.
            AppDomain currentDomain = AppDomain.CurrentDomain;
            string    typeName      = string.Format("{0}Proxy", baseType.Name);
            string    assemblyName  = string.Format("{0}Assembly", typeName);
            string    moduleName    = string.Format("{0}Module", typeName);

            // Define different behaviors for debug and release so that we can make debugging easier.
            AssemblyName name = new AssemblyName(assemblyName);

#if DEBUG
            AssemblyBuilder assemblyBuilder = currentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
            ModuleBuilder   moduleBuilder   = assemblyBuilder.DefineDynamicModule(moduleName, string.Format("{0}.mod", moduleName), true);
#else
            AssemblyBuilder assemblyBuilder = currentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
            ModuleBuilder   moduleBuilder   = assemblyBuilder.DefineDynamicModule(moduleName);
#endif
            // Define type attributes
            const TypeAttributes TypeAttributes = TypeAttributes.AutoClass |
                                                  TypeAttributes.Class |
                                                  TypeAttributes.Public |
                                                  TypeAttributes.BeforeFieldInit;

            // Define the type.
            TypeBuilder typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes, baseType);

            // Emit the default constructors for this proxy so that classes without parameterless constructors
            // can be proxied.
            ConstructorInfo[] constructors = baseType.GetConstructors();
            foreach (ConstructorInfo constructorInfo in constructors)
            {
                ConstructorEmitter.Emit(typeBuilder, constructorInfo);
            }

            // Emit the IProxy IInterceptor property.
            FieldInfo interceptorField = InterceptorEmitter.Emit(typeBuilder);

            // Emit each property that is to be intercepted.
            MethodInfo[]             methods   = baseType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
            IEnumerable <MethodInfo> proxyList = this.BuildPropertyList(methods);

            foreach (MethodInfo methodInfo in proxyList)
            {
                PropertyEmitter.Emit(typeBuilder, methodInfo, interceptorField);
            }

            // Create and return.
            return(typeBuilder.CreateType());
        }
        /// <summary>
        /// Creates an un-cached proxy class.
        /// </summary>
        /// <param name="baseType">The base <see cref="Type"/> to proxy.</param>
        /// <param name="properties">The collection of property names to map.</param>
        /// <returns>
        /// The proxy <see cref="Type"/>.
        /// </returns>
        private Type CreateUncachedProxyType(Type baseType, IEnumerable <string> properties)
        {
            // Create a dynamic assembly and module to store the proxy.
            AppDomain currentDomain = AppDomain.CurrentDomain;
            string    typeName      = $"{baseType.Name}Proxy";
            string    assemblyName  = $"{typeName}Assembly";
            string    moduleName    = $"{typeName}Module";

            // Define different behaviors for debug and release so that we can make debugging easier.
            var             name = new AssemblyName(assemblyName);
            AssemblyBuilder assemblyBuilder;

#if DEBUG
            assemblyBuilder = currentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(moduleName, $"{moduleName}.mod", true);

            // Add a debuggable attribute to the assembly saying to disable optimizations
            Type            daType    = typeof(DebuggableAttribute);
            ConstructorInfo daCtor    = daType.GetConstructor(new[] { typeof(DebuggableAttribute.DebuggingModes) });
            var             daBuilder = new CustomAttributeBuilder(
                daCtor,
                new object[] { DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.Default });
            assemblyBuilder.SetCustomAttribute(daBuilder);
#else
            assemblyBuilder = currentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(moduleName);
#endif

            // Define type attributes
            const TypeAttributes typeAttributes = TypeAttributes.AutoClass |
                                                  TypeAttributes.Class |
                                                  TypeAttributes.Public |
                                                  TypeAttributes.BeforeFieldInit;

            // Define the type.
            TypeBuilder typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes, baseType);

            // Emit the default constructors for this proxy so that classes without parameterless constructors
            // can be proxied.
            ConstructorInfo[] constructors = baseType.GetConstructors();
            foreach (ConstructorInfo constructorInfo in constructors)
            {
                ConstructorEmitter.Emit(typeBuilder, constructorInfo);
            }

            // Emit the IProxy IInterceptor property.
            FieldInfo interceptorField = InterceptorEmitter.Emit(typeBuilder);

            // Collect and filter our list of properties to intercept.
            MethodInfo[] methods = baseType.GetMethods(BindingFlags.Public | BindingFlags.Instance);

            IEnumerable <MethodInfo> proxyList = this.BuildPropertyList(methods)
                                                 .Where(m => properties.Contains(m.Name.Substring(4), StringComparer.OrdinalIgnoreCase));

            // Emit each property that is to be intercepted.
            foreach (MethodInfo methodInfo in proxyList)
            {
                PropertyEmitter.Emit(typeBuilder, methodInfo, interceptorField);
            }

            // Create and return.
            Type result = typeBuilder.CreateType();

#if DEBUG
            assemblyBuilder.Save(typeName + ".dll");
#endif
            return(result);
        }