Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / xsp / System / Web / Util / FactoryGenerator.cs / 1 / FactoryGenerator.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- #if !DONTUSEFACTORYGENERATOR using System; using System.Reflection; using System.Reflection.Emit; using System.Threading; using System.Security; using System.Security.Permissions; namespace System.Web.Util { /* * 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 = (ISomeInterface) 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) 2003 Microsoft Corporation */ internal class FactoryGenerator { private Type _factoryInterface; private Type _returnedType; private MethodInfo _methodToOverride; private ModuleBuilder _dynamicModule = null; private Type[] _emptyParameterList = new Type[] { }; private Type[] _interfacesToImplement; internal 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", new Type[0]); if (_methodToOverride.ReturnType != _returnedType) { throw new ArgumentException(SR.GetString(SR.FactoryInterface)); } // This will be needed later, when building the dynamic class. _interfacesToImplement = new Type[1]; _interfacesToImplement[0] = factoryInterface; } // A type must be public and have a parameterless constructor, in order for us to be able to // create a factory for the type. Throws if either of these conditions are not true. internal static void CheckPublicParameterlessConstructor(Type type) { if (type == null) { throw new ArgumentNullException("type"); } if (!(type.IsPublic || type.IsNestedPublic)) { throw new InvalidOperationException(SR.GetString(SR.FactoryGenerator_TypeNotPublic, type.Name)); } ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); if (constructor == null) { throw new InvalidOperationException(SR.GetString(SR.FactoryGenerator_TypeHasNoParameterlessConstructor, type.Name)); } } private static String GetUniqueCompilationName() { return Guid.NewGuid().ToString().Replace('-', '_'); } [ReflectionPermission(SecurityAction.Assert, Flags=ReflectionPermissionFlag.ReflectionEmit)] Type GetFactoryTypeWithAssert(Type type) { CheckPublicParameterlessConstructor(type); // Create the dynamic assembly if needed. Type factoryType; if (_dynamicModule == null) { lock (this) { 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 = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run, 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, TypeAttributes.Public, typeof(Object), _interfacesToImplement); // Define the CreateInstance method. It must be virtual to be an interface implementation. MethodBuilder method = factoryTypeBuilder.DefineMethod("CreateInstance", MethodAttributes.Public | MethodAttributes.Virtual, _returnedType, null); // Generate IL. The generated IL corresponds to "return new type()" // newobj// ret ILGenerator il = method.GetILGenerator(); ConstructorInfo cons = type.GetConstructor(Type.EmptyTypes); il.Emit(OpCodes.Newobj, cons); il.Emit(OpCodes.Ret); // Specify that this method implements CreateInstance from the inherited interface. factoryTypeBuilder.DefineMethodOverride(method, _methodToOverride); // Bake in the type. factoryType = factoryTypeBuilder.CreateType(); return factoryType; } internal IWebObjectFactory CreateFactory(Type type) { Debug.Trace("FactoryGenerator", "Creating generator for type " + type.FullName); Type factoryType = GetFactoryTypeWithAssert(type); // Create the type. This is the only place where Activator.CreateInstance is used, // reducing the calls to it from 1 per instance to 1 per type. return (IWebObjectFactory) Activator.CreateInstance(factoryType); } } } #endif // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- #if !DONTUSEFACTORYGENERATOR using System; using System.Reflection; using System.Reflection.Emit; using System.Threading; using System.Security; using System.Security.Permissions; namespace System.Web.Util { /* * 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 = (ISomeInterface) 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) 2003 Microsoft Corporation */ internal class FactoryGenerator { private Type _factoryInterface; private Type _returnedType; private MethodInfo _methodToOverride; private ModuleBuilder _dynamicModule = null; private Type[] _emptyParameterList = new Type[] { }; private Type[] _interfacesToImplement; internal 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", new Type[0]); if (_methodToOverride.ReturnType != _returnedType) { throw new ArgumentException(SR.GetString(SR.FactoryInterface)); } // This will be needed later, when building the dynamic class. _interfacesToImplement = new Type[1]; _interfacesToImplement[0] = factoryInterface; } // A type must be public and have a parameterless constructor, in order for us to be able to // create a factory for the type. Throws if either of these conditions are not true. internal static void CheckPublicParameterlessConstructor(Type type) { if (type == null) { throw new ArgumentNullException("type"); } if (!(type.IsPublic || type.IsNestedPublic)) { throw new InvalidOperationException(SR.GetString(SR.FactoryGenerator_TypeNotPublic, type.Name)); } ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); if (constructor == null) { throw new InvalidOperationException(SR.GetString(SR.FactoryGenerator_TypeHasNoParameterlessConstructor, type.Name)); } } private static String GetUniqueCompilationName() { return Guid.NewGuid().ToString().Replace('-', '_'); } [ReflectionPermission(SecurityAction.Assert, Flags=ReflectionPermissionFlag.ReflectionEmit)] Type GetFactoryTypeWithAssert(Type type) { CheckPublicParameterlessConstructor(type); // Create the dynamic assembly if needed. Type factoryType; if (_dynamicModule == null) { lock (this) { 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 = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run, 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, TypeAttributes.Public, typeof(Object), _interfacesToImplement); // Define the CreateInstance method. It must be virtual to be an interface implementation. MethodBuilder method = factoryTypeBuilder.DefineMethod("CreateInstance", MethodAttributes.Public | MethodAttributes.Virtual, _returnedType, null); // Generate IL. The generated IL corresponds to "return new type()" // newobj// ret ILGenerator il = method.GetILGenerator(); ConstructorInfo cons = type.GetConstructor(Type.EmptyTypes); il.Emit(OpCodes.Newobj, cons); il.Emit(OpCodes.Ret); // Specify that this method implements CreateInstance from the inherited interface. factoryTypeBuilder.DefineMethodOverride(method, _methodToOverride); // Bake in the type. factoryType = factoryTypeBuilder.CreateType(); return factoryType; } internal IWebObjectFactory CreateFactory(Type type) { Debug.Trace("FactoryGenerator", "Creating generator for type " + type.FullName); Type factoryType = GetFactoryTypeWithAssert(type); // Create the type. This is the only place where Activator.CreateInstance is used, // reducing the calls to it from 1 per instance to 1 per type. return (IWebObjectFactory) Activator.CreateInstance(factoryType); } } } #endif // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HandlerFactoryWrapper.cs
- ServiceModelEnumValidator.cs
- TypeUsage.cs
- DBCSCodePageEncoding.cs
- Buffer.cs
- XomlDesignerLoader.cs
- ClientTargetSection.cs
- ObfuscateAssemblyAttribute.cs
- HtmlAnchor.cs
- RootBrowserWindow.cs
- EntityDataSourceView.cs
- BitmapEffect.cs
- EnumerableValidator.cs
- CustomBindingElement.cs
- CustomTypeDescriptor.cs
- XmlSecureResolver.cs
- OleDbStruct.cs
- PerspectiveCamera.cs
- IteratorDescriptor.cs
- ProxyWebPartConnectionCollection.cs
- Button.cs
- ListSourceHelper.cs
- FileDialog_Vista_Interop.cs
- ConstNode.cs
- PrivateFontCollection.cs
- HoistedLocals.cs
- CombinedGeometry.cs
- RegexMatchCollection.cs
- SynchronizedInputHelper.cs
- WebServiceErrorEvent.cs
- DataControlFieldCell.cs
- BaseComponentEditor.cs
- BufferedStream.cs
- Lease.cs
- RadioButtonRenderer.cs
- DBPropSet.cs
- XmlAttributes.cs
- TransactionFlowBindingElementImporter.cs
- String.cs
- XmlNodeComparer.cs
- EventMap.cs
- XmlMtomWriter.cs
- CommandID.cs
- FormatControl.cs
- ControlIdConverter.cs
- BindingSource.cs
- ZipArchive.cs
- ListItem.cs
- GridViewHeaderRowPresenter.cs
- WindowsSecurityTokenAuthenticator.cs
- EntitySetDataBindingList.cs
- WebPartAddingEventArgs.cs
- BitmapEffectDrawing.cs
- CompilerHelpers.cs
- panel.cs
- EmptyStringExpandableObjectConverter.cs
- ServiceNameElementCollection.cs
- rsa.cs
- Clock.cs
- ToolStripProgressBar.cs
- UnknownWrapper.cs
- processwaithandle.cs
- LinqDataSource.cs
- Sql8ExpressionRewriter.cs
- HttpCapabilitiesSectionHandler.cs
- StringDictionary.cs
- XmlRawWriter.cs
- ModuleElement.cs
- OdbcParameterCollection.cs
- SessionStateSection.cs
- MemberPathMap.cs
- FileCodeGroup.cs
- CompositionDesigner.cs
- FeatureSupport.cs
- XmlAttribute.cs
- RtfControlWordInfo.cs
- SequenceFullException.cs
- COM2PropertyPageUITypeConverter.cs
- CalendarTable.cs
- DataGridViewCellValueEventArgs.cs
- SymbolTable.cs
- ConstrainedDataObject.cs
- MsmqAppDomainProtocolHandler.cs
- PropertyGrid.cs
- VBIdentifierNameEditor.cs
- HwndKeyboardInputProvider.cs
- DetailsViewPageEventArgs.cs
- XmlUTF8TextReader.cs
- PolyLineSegment.cs
- PrimitiveXmlSerializers.cs
- GuidelineCollection.cs
- CriticalFinalizerObject.cs
- FileSystemInfo.cs
- DbUpdateCommandTree.cs
- EntityClientCacheEntry.cs
- InfoCardRSAPKCS1KeyExchangeFormatter.cs
- SupportsEventValidationAttribute.cs
- BindingOperations.cs
- KeyManager.cs
- ServiceProviders.cs