File: UI\MobileControls\FactoryGenerator.cs
Project: ndp\fx\src\mit\System\Web\System.Web.Mobile.csproj (System.Web.Mobile)
// <copyright file="FactoryGenerator.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>                                                                
using System;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
using System.Security;
using System.Security.Permissions;
using System.Web.Util;
namespace System.Web.UI.MobileControls {
     * Factory Generator class
     * A factory generator is useful for cases where a large number of late-bound
     * classes need to be instantiated.
     * Normally, to create an instance of type t, you call the following code:
     *      ISomeInterface o = Activator.CreateInstance(t);
     * This assumes that the default constructor is used, and that the type t
     * implements the interface ISomeInterface.
     * The factory generator, on the other hand, can use reflection emit APIs
     * to dynamically generate a class factory for t. The generated class has
     * the equivalent of the following code:
     *      class X : ISomeInterfaceFactory
     *      {
     *          public ISomeInterface CreateInstance()
     *          {
     *              return new t();
     *          }
     *      }
     * It then instantiates and returns an object of this type. You can then
     * call CreateInstance to create an instance of the type, which is 
     * significantly faster.
     * A single instance of a FactoryGenerator can generate factories for 
     * multiple types. However, it builds all these types into a single
     * dynamically generated assembly. CLR implementation prevents this
     * assembly from being unloaded until the process exits.
     * The FactoryGenerator is (almost) a templated type. It takes two
     * types in its constructor:
     *   returnedType is the type common to all classes for which factories
     *      are to be generated. In the example above, this would be 
     *      ISomeInterface.
     *   factoryInterface is the interface implemented by the dynamically
     *      generated class factory, and should include a method named
     *      CreateInstance, that takes no parameters and returns an object
     *      of the type specified by returnedType. In the example above,
     *      this would be ISomeInterfaceFactory.
     * Copyright (c) 2001 Microsoft Corporation
    [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see")]
    internal class FactoryGenerator {
        private Type _factoryInterface;
        private Type _returnedType;
        private MethodInfo _methodToOverride;
        private ModuleBuilder _dynamicModule = null;
        private Type[] _emptyParameterList = new Type[] { };
        private Type[] _interfacesToImplement;
        private object _instanceLock = new object();
        private Hashtable _factoryTable = new Hashtable();
        private static FactoryGenerator _factoryGenerator;
        private static object _factoryGeneratorLock = new object();
        // VSWhidbey 459555: We only need one instance of FactoryGenerator per app domain,
        // so we mark all constructors as private so enforce the usage of the static
        // StaticFactoryGenerator property.
        private FactoryGenerator() : this(typeof(object), typeof(IWebObjectFactory)) { }
        private FactoryGenerator(Type returnedType, Type factoryInterface) {
            _returnedType = returnedType;
            _factoryInterface = factoryInterface;
            // Get the CreateInstance method, and make sure it has
            // the correct signature.
            _methodToOverride = factoryInterface.GetMethod("CreateInstance");
            if (_methodToOverride.ReturnType != _returnedType ||
                _methodToOverride.GetParameters().Length != 0) {
                throw new InvalidOperationException(SR.GetString(SR.FactoryGenerator_Error_FactoryInterface));
            // This will be needed later, when building the dynamic class.
            _interfacesToImplement = new Type[1];
            _interfacesToImplement[0] = factoryInterface;
        internal static FactoryGenerator StaticFactoryGenerator {
            get {
                if (_factoryGenerator == null) {
                    lock (_factoryGeneratorLock) {
                        if (_factoryGenerator == null) {
                            _factoryGenerator = new FactoryGenerator();
                return _factoryGenerator;
        private static String GetUniqueCompilationName() {
            return Guid.NewGuid().ToString().Replace('-', '_');
        internal /*public*/ Object GetFactory(Type type) {
            // Create the dynamic assembly if needed.
            Object o = _factoryTable[type];
            if (o != null) {
                return o;
            lock (_instanceLock) {
                o = _factoryTable[type];
                if (o != null) {
                    return o;
                Type factoryType;
                if (_dynamicModule == null) {
                    // Use a unique name for each assembly.
                    String name = GetUniqueCompilationName();
                    AssemblyName assemblyName = new AssemblyName();
                    assemblyName.Name = "A_" + name;
                    // Create a new assembly.
                    AssemblyBuilder newAssembly =
                                                                null, //directory to persist assembly
                                                                null, //evidence copied from caller
                                                                null, //requiredPermissions
                                                                null, //optionalPermissions
                                                                null, //refusedPermissions
                                                                true //isSynchronized
                    // Create a single module in the assembly.
                    _dynamicModule = newAssembly.DefineDynamicModule("M_" + name);
                // Give the factory a unique name.
                String typeName = GetUniqueCompilationName();
                TypeBuilder factoryTypeBuilder = _dynamicModule.DefineType("T_" + typeName,
                // Define the CreateInstance method. It must be virtual to be an interface implementation.
                MethodBuilder method = factoryTypeBuilder.DefineMethod("CreateInstance",
                                                                       MethodAttributes.Public |
                // Generate IL. The generated IL corresponds to "return new type()"
                //      newobj <type_constructor>
                //      ret
                ILGenerator il = method.GetILGenerator();
                ConstructorInfo cons = type.GetConstructor(_emptyParameterList);
                il.Emit(OpCodes.Newobj, cons);
                // Specify that this method implements CreateInstance from the inherited interface.
                factoryTypeBuilder.DefineMethodOverride(method, _methodToOverride);
                // Bake in the type.
                factoryType = factoryTypeBuilder.CreateType();
                // Create the type. This is the only place where Activator.CreateInstance is used,
                // reducing the calls to it from 1 per adapter instance to 1 per adapter type.
                object factory = Activator.CreateInstance(factoryType);
                _factoryTable[type] = factory;
                return factory;