Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / xsp / System / Web / Compilation / BuildResult.cs / 8 / BuildResult.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /********************************* BuildResult BuildResultCompileError BuildResultCompiledAssemblyBase BuildResultCompiledAssembly BuildResultCustomString BuildResultMainCodeAssembly BuildResultResourceAssembly BuildResultCompiledType BuildResultCompiledTemplateType BuildResultCompiledGlobalAsaxType ImageGeneratorBuildResultCompiledType BuildResultNoCompileTemplateControl BuildResultNoCompilePage BuildResultNoCompileUserControl BuildResultNoCompileMasterPage BuildResultCodeCompileUnit **********************************/ namespace System.Web.Compilation { using System; using System.IO; using System.CodeDom; using System.CodeDom.Compiler; using System.Collections; using System.ComponentModel.Design; using System.Globalization; using System.Reflection; using System.Runtime.Serialization.Formatters.Binary; using System.Security; using System.Security.Permissions; using System.Threading; using System.Web.Caching; using System.Web.Hosting; using System.Web.Util; using System.Web.UI; using System.Web.Configuration; internal enum BuildResultTypeCode { Invalid=-1, BuildResultCompiledAssembly = 1, BuildResultCompiledType = 2, BuildResultCompiledTemplateType = 3, #if ORCAS ImageGeneratorBuildResultCompiledType = 4, #endif BuildResultCustomString = 5, BuildResultMainCodeAssembly = 6, BuildResultCodeCompileUnit = 7, BuildResultCompiledGlobalAsaxType = 8, BuildResultResourceAssembly = 9, } internal abstract class BuildResult { // const masks into the BitVector32 // The 16 lower bits come from the BuildProviderResultFlags enumeration // and should not be used here. They are set from calling // BuildProvider.GetResultFlags. protected const int usesCacheDependency = 0x00010000; protected const int usesExistingAssembly = 0x00020000; private const int noMemoryCache = 0x00040000; protected const int hasAppOrSessionObjects = 0x00080000; protected const int dependenciesHashComputed = 0x00100000; #pragma warning disable 0649 protected SimpleBitVector32 _flags; #pragma warning restore 0649 internal static BuildResult CreateBuildResultFromCode(BuildResultTypeCode code, VirtualPath virtualPath) { BuildResult ret = null; switch (code) { case BuildResultTypeCode.BuildResultCompiledAssembly: ret = new BuildResultCompiledAssembly(); break; case BuildResultTypeCode.BuildResultCompiledType: ret = new BuildResultCompiledType(); break; case BuildResultTypeCode.BuildResultCompiledTemplateType: ret = new BuildResultCompiledTemplateType(); break; case BuildResultTypeCode.BuildResultCompiledGlobalAsaxType: ret = new BuildResultCompiledGlobalAsaxType(); break; #if ORCAS case BuildResultTypeCode.ImageGeneratorBuildResultCompiledType: ret = new ImageGeneratorBuildResultCompiledType(); break; #endif case BuildResultTypeCode.BuildResultCustomString: ret = new BuildResultCustomString(); break; case BuildResultTypeCode.BuildResultMainCodeAssembly: ret = new BuildResultMainCodeAssembly(); break; case BuildResultTypeCode.BuildResultResourceAssembly: ret = new BuildResultResourceAssembly(); break; case BuildResultTypeCode.BuildResultCodeCompileUnit: ret = new BuildResultCodeCompileUnit(); break; default: Debug.Assert(false, "code=" + code); return null; } ret.VirtualPath = virtualPath; // Set _nextUpToDateCheck to MinValue, to make sure the next call to IsUpToDate() // actually makes the check ret._nextUpToDateCheck = DateTime.MinValue; return ret; } internal virtual BuildResultTypeCode GetCode() { return BuildResultTypeCode.Invalid; } internal int Flags { get { return _flags.IntegerValue; } set { _flags.IntegerValue = value; } } private VirtualPath _virtualPath; internal VirtualPath VirtualPath { get { return _virtualPath; } set { _virtualPath = value; } } // Are the BuildResult's VirtualPathDependencies being monitored by a CacheDependency. // If so, then we don't need to check validity after finding the BuildResult in the // memory cache (since it would have been kicked out if it was invalid). internal bool UsesCacheDependency { get { return _flags[usesCacheDependency]; } set { _flags[usesCacheDependency] = value; } } // Does the appdomain need to be shut down when this item becomes invalid? internal bool ShutdownAppDomainOnChange { get { return _flags[(int)BuildProviderResultFlags.ShutdownAppDomainOnChange]; } } // The list of files (virtual paths) it depends on (for caching purpose) private ArrayList _virtualPathDependencies; internal ICollection VirtualPathDependencies { get { return _virtualPathDependencies; } } // Hash code based on all the source file dependencies private string _virtualPathDependenciesHash; internal string VirtualPathDependenciesHash { get { EnsureVirtualPathDependenciesHashComputed(); return _virtualPathDependenciesHash; } set { Debug.Assert(_virtualPathDependenciesHash == null); _virtualPathDependenciesHash = value; } } internal bool DependenciesHashComputed { get { return _flags[dependenciesHashComputed]; } } internal void EnsureVirtualPathDependenciesHashComputed() { if (!DependenciesHashComputed) { // We shouldn't already have a hash Debug.Assert(_virtualPathDependenciesHash == null); // Sort the source dependencies to make the hash code predictable if (_virtualPathDependencies != null) _virtualPathDependencies.Sort(InvariantComparer.Default); _virtualPathDependenciesHash = ComputeSourceDependenciesHashCode(null /*virtualPath*/); // It's computed, but it could be null _flags[dependenciesHashComputed] = true; } } // These fields are used to make sure we only check the UpToDate status // of the build result once every few seconds (since it's expensive) private DateTime _nextUpToDateCheck = DateTime.Now.AddSeconds(UpdateInterval); private int _lock; private const int UpdateInterval = 2; // 2 seconds internal void SetVirtualPathDependencies(ArrayList sourceDependencies) { Debug.Assert(_virtualPathDependencies == null); Debug.Assert(sourceDependencies != null); _virtualPathDependencies = sourceDependencies; } internal void AddVirtualPathDependencies(ICollection sourceDependencies) { if (sourceDependencies == null) return; if (_virtualPathDependencies == null) { _virtualPathDependencies = new ArrayList(sourceDependencies); } else { _virtualPathDependencies.AddRange(sourceDependencies); } } /* * Can the result be unloaded from memory. Most objects can, but things like * Assemblies and Types can't. This is used to determine the caching behavior. */ internal virtual bool IsUnloadable { get { return true; } } /* * Should the result be cached to disk. Usually yes, but for things like compile * errors, we only cache them to memory. */ internal virtual bool CacheToDisk { get { return true; } } /* * Should the result be cached to memory. Usually yes, but for things like top level * assemblies, we only cache them to disk. */ internal bool CacheToMemory { get { return !_flags[noMemoryCache]; } set { _flags[noMemoryCache] = !value; } } /* * Time the build result should expire from the memory cache */ internal virtual DateTime MemoryCacheExpiration { get { return Cache.NoAbsoluteExpiration; } } /* * Sliding expiration for the build result */ internal virtual TimeSpan MemoryCacheSlidingExpiration { get { return Cache.NoSlidingExpiration; } } protected void ReadPreservedFlags(PreservationFileReader pfr) { string s = pfr.GetAttribute("flags"); if ((s != null) && (s.Length != 0)) { Flags = Int32.Parse(s, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture); } } internal virtual void GetPreservedAttributes(PreservationFileReader pfr) { ReadPreservedFlags(pfr); } internal virtual void SetPreservedAttributes(PreservationFileWriter pfw) { if (Flags != 0) { pfw.SetAttribute("flags", Flags.ToString("x", CultureInfo.InvariantCulture)); } } /* * Tell the BuildResult that its dependencies are not up to date, in order * to give it a chance to do some cleanup. */ internal virtual void RemoveOutOfDateResources(PreservationFileReader pfw) {} // Compute the current hash code of the preserved data. Return 0 if the // hash code is not valid. internal long ComputeHashCode(long hashCode) { return ComputeHashCode(hashCode, 0); } internal long ComputeHashCode(long hashCode1, long hashCode2) { HashCodeCombiner hashCodeCombiner = new HashCodeCombiner(); // If a hashcode was passed in, start with it if (hashCode1 != 0) hashCodeCombiner.AddObject(hashCode1); if (hashCode2 != 0) hashCodeCombiner.AddObject(hashCode2); ComputeHashCode(hashCodeCombiner); return hashCodeCombiner.CombinedHash; } /* * Compute the hash code of what this buid result depends on, excluding * the virtual path dependencies (which are handled separately by * VirtualPathDependenciesHash). */ protected virtual void ComputeHashCode(HashCodeCombiner hashCodeCombiner) { } internal virtual string ComputeSourceDependenciesHashCode(VirtualPath virtualPath) { // Return an empty string if there are no dependencies. This is different from // null, which means 'don't cache' if (VirtualPathDependencies == null) return String.Empty; // If no virtual path was passed in, use the one from the BuildResult if (virtualPath == null) virtualPath = VirtualPath; return virtualPath.GetFileHash(VirtualPathDependencies); } internal bool IsUpToDate(VirtualPath virtualPath) { // This should never be called on a BuildResult that has already been // determined to be out of date. Debug.Assert(_lock >= 0); if (_lock < 0) return false; // Don't check more than every two seconds DateTime now = DateTime.Now; // Due to bug 214038, CBM can be called multiple times in a very short time. if (now < _nextUpToDateCheck && !BuildManagerHost.InClientBuildManager) { Debug.Trace("BuildResult", "IsUpToDate: true since called less than 2 seconds ago. " + _nextUpToDateCheck + "," + now); return true; } // If we don't get the lock, just say it's up to date without checking if (Interlocked.CompareExchange(ref _lock, 1, 0) != 0) { Debug.Trace("BuildResult", "IsUpToDate returning true because it didn't get the lock"); return true; } string newHashCode; try { newHashCode = ComputeSourceDependenciesHashCode(virtualPath); } catch { // Make sure to release the lock if something throws. Interlocked.Exchange(ref _lock, 0); throw; } // Check if we're up to date. A null hash code means the cache should not be used. if (newHashCode == null || newHashCode != _virtualPathDependenciesHash) { Debug.Trace("BuildResult", "IsUpToDate: '" + VirtualPath + "' is out of date"); // Set the lock to -1 to mark that we're not up to date _lock = -1; return false; } Debug.Trace("BuildResult", "IsUpToDate: '" + VirtualPath + "' is up to date"); // We're up to date. Remember the time we checked, and reset the lock _nextUpToDateCheck = now.AddSeconds(UpdateInterval); Interlocked.Exchange(ref _lock, 0); return true; } } internal class BuildResultCompileError: BuildResult { // The exception in case we cached the result of a failed compilation private HttpCompileException _compileException; internal HttpCompileException CompileException { get { return _compileException; } } internal BuildResultCompileError(VirtualPath virtualPath, HttpCompileException compileException) { VirtualPath = virtualPath; _compileException = compileException; } /* * Don't cache compile errors to disk */ internal override bool CacheToDisk { get { return false; } } internal override DateTime MemoryCacheExpiration { get { // Only cache compile errors for 10 seconds. This is to get us out of trouble // if the compilation fails due to some strange timing issue, and might succeed // on retry (VSWhidbey 483169) return DateTime.UtcNow.AddSeconds(10); } } } internal class BuildResultCustomString: BuildResultCompiledAssembly { private string _customString; internal BuildResultCustomString() {} internal BuildResultCustomString(Assembly a, string customString) : base(a) { Debug.Assert(customString != null); _customString = customString; } internal override BuildResultTypeCode GetCode() { return BuildResultTypeCode.BuildResultCustomString; } internal override void GetPreservedAttributes(PreservationFileReader pfr) { base.GetPreservedAttributes(pfr); // Retrieve the custom string _customString = pfr.GetAttribute("customString"); Debug.Assert(_customString != null); } internal override void SetPreservedAttributes(PreservationFileWriter pfw) { base.SetPreservedAttributes(pfw); // Preserve the custom string pfw.SetAttribute("customString", _customString); } internal string CustomString { get { return _customString; } } } internal abstract class BuildResultCompiledAssemblyBase: BuildResult { internal bool UsesExistingAssembly { get { return _flags[usesExistingAssembly]; } set { _flags[usesExistingAssembly] = value; } } // Assemblies are *not* unloadable, so only allow the build result to be unloaded // if there is no assembly internal override bool IsUnloadable { get { return (ResultAssembly == null); } } internal abstract Assembly ResultAssembly { get; set; } static private string s_codegenDir = null; internal static Assembly GetPreservedAssembly(PreservationFileReader pfr) { string assemblyName = pfr.GetAttribute("assembly"); if (assemblyName == null) return null; // Try to load the assembly try { Assembly a = Assembly.Load(assemblyName); // VSWhidbey 564168 // Do not load assemblies or assemblies with references that // do not exist or are marked for deletion // It is possible that Assembly.Load succeeds, even though the // underlying DLL was renamed (to .delete). In that case, we should // not return the assembly, as we would be unable to compile with // a reference to it. if (AssemblyIsInvalid(a)) { // Throw some exception, since the caller doesn't expect null throw new InvalidOperationException(); } // Check references of the assembly, and make sure they exists, // otherwise throw an exception. CheckAssemblyIsValid(a, new Hashtable()); return a; } catch { Debug.Trace("BuildResult", "GetPreservedAssembly: couldn't load assembly '" + assemblyName + "'; deleting associated files."); // Remove the assembly and all the associated files pfr.DiskCache.RemoveAssemblyAndRelatedFiles(assemblyName); throw; } } // DevDiv Bug 98735 // Go through the assembly and all references (including deeper levels) to make sure that // each referenced assembly exists and does not have a dot delete. // If any referenced assembly is removed or marked for deletion, // we invalidate the base assembly by throwing an InvalidOperationException private static void CheckAssemblyIsValid(Assembly a, Hashtable checkedAssemblies) { // Keep track of which assemblies we already checked so we can skip them checkedAssemblies.Add(a, null); foreach (AssemblyName aName in a.GetReferencedAssemblies()) { Assembly referencedAssembly = Assembly.Load(aName); // If it is in the GAC, skip checking it if (referencedAssembly.GlobalAssemblyCache) continue; // Do not validate assemblies other than those we generate. // If the assembly is NOT in the codegen folder, skip it if (!AssemblyIsInCodegenDir(referencedAssembly)) continue; // If we have already checked an assembly, don't check it again if (!checkedAssemblies.Contains(referencedAssembly)) { if (AssemblyIsInvalid(referencedAssembly)) throw new InvalidOperationException(); // Visit nested referenced assemblies CheckAssemblyIsValid(referencedAssembly, checkedAssemblies); } } } private static bool AssemblyIsInCodegenDir(Assembly a) { string path = Util.GetAssemblyCodeBase(a); FileInfo f = new FileInfo(path); string assemblyDir = FileUtil.RemoveTrailingDirectoryBackSlash(f.Directory.FullName); if (s_codegenDir == null) { s_codegenDir = FileUtil.RemoveTrailingDirectoryBackSlash(HttpRuntime.CodegenDir); } // check if the assembly is directly under codegen // Shadow-copied assemblies are in a deeper directory (eg myapp\zzz\yyy\assembly\dl3\xxxx) if (string.Equals(assemblyDir, s_codegenDir, StringComparison.OrdinalIgnoreCase)) return true; return false; } private static bool AssemblyIsInvalid(Assembly a) { // If the file does not exist, or if it has a .delete file, // then it should not be used string path = Util.GetAssemblyCodeBase(a); return (!FileUtil.FileExists(path) || DiskBuildResultCache.HasDotDeleteFile(path)); } internal override void SetPreservedAttributes(PreservationFileWriter pfw) { base.SetPreservedAttributes(pfw); if (ResultAssembly != null) { string assemblyName; if (ResultAssembly.GlobalAssemblyCache) { // If it's in the GAC, store the full name (VSWhidbey 384416) assemblyName = ResultAssembly.FullName; } else { // Otherwise, store the short name, to avoid uselessly growing the preservation file assemblyName = ResultAssembly.GetName().Name; } pfw.SetAttribute("assembly", assemblyName); } } /* * Tell the BuildResult that its dependencies are not up to date, in order * to give it a chance to do some cleanup. */ internal override void RemoveOutOfDateResources(PreservationFileReader pfr) { // If the preservation file is pointing to an assembly that was not built // for this result, do not attempt to clean it up (see VSWhidbey 74094) ReadPreservedFlags(pfr); if (UsesExistingAssembly) return; // Remove the assembly and all the associated files string assemblyName = pfr.GetAttribute("assembly"); if (assemblyName != null) { pfr.DiskCache.RemoveAssemblyAndRelatedFiles(assemblyName); } } protected override void ComputeHashCode(HashCodeCombiner hashCodeCombiner) { base.ComputeHashCode(hashCodeCombiner); // Make the hash code depend on the relevant contents of theconfig section CompilationSection compConfig = RuntimeConfig.GetConfig(VirtualPath).Compilation; hashCodeCombiner.AddObject(compConfig.RecompilationHash); } } internal class BuildResultCompiledAssembly: BuildResultCompiledAssemblyBase { private Assembly _assembly; internal BuildResultCompiledAssembly() {} internal BuildResultCompiledAssembly(Assembly a) { _assembly = a; } internal override BuildResultTypeCode GetCode() { return BuildResultTypeCode.BuildResultCompiledAssembly; } internal override Assembly ResultAssembly { get { return _assembly; } set { _assembly = value; } } internal override void GetPreservedAttributes(PreservationFileReader pfr) { base.GetPreservedAttributes(pfr); ResultAssembly = GetPreservedAssembly(pfr); } } /* * Same as BuildResultCompiledAssembly, but with some special behavior specific to * the main code assembly. Specifically, it adds support for the AppInitialize method * and for VB's My.* */ internal class BuildResultMainCodeAssembly: BuildResultCompiledAssembly { private const string appInitializeMethodName = "AppInitialize"; private MethodInfo _appInitializeMethod; internal BuildResultMainCodeAssembly() {} internal BuildResultMainCodeAssembly(Assembly a) : base(a) { // Look for an AppInitialize static method in the assembly FindAppInitializeMethod(); } internal override BuildResultTypeCode GetCode() { return BuildResultTypeCode.BuildResultMainCodeAssembly; } internal override void GetPreservedAttributes(PreservationFileReader pfr) { base.GetPreservedAttributes(pfr); // Does the assembly have an AppInitialize method? string appInitializeClass = pfr.GetAttribute("appInitializeClass"); if (appInitializeClass != null) { // Get the Type that contains the method Type appInitializeType = ResultAssembly.GetType(appInitializeClass); Debug.Assert(appInitializeType != null); // Find the method _appInitializeMethod = FindAppInitializeMethod(appInitializeType); Debug.Assert(_appInitializeMethod != null); } } internal override void SetPreservedAttributes(PreservationFileWriter pfw) { base.SetPreservedAttributes(pfw); // If there is an AppInitialize method, save the class name that it's in if (_appInitializeMethod != null) { pfw.SetAttribute("appInitializeClass", _appInitializeMethod.ReflectedType.FullName); } } private void FindAppInitializeMethod() { Debug.Assert(_appInitializeMethod == null); // Look in all the public types in the assembly foreach (Type t in ResultAssembly.GetExportedTypes()) { // Look for an AppInitialize method MethodInfo tmpAppInitializeMethod = FindAppInitializeMethod(t); if (tmpAppInitializeMethod != null) { // Make sure we didn't already have one if (_appInitializeMethod != null) { throw new HttpException(SR.GetString( SR.Duplicate_appinitialize, _appInitializeMethod.ReflectedType.FullName, t.FullName)); } // Keep track of the method _appInitializeMethod = tmpAppInitializeMethod; } } } private MethodInfo FindAppInitializeMethod(Type t) { return t.GetMethod(appInitializeMethodName, BindingFlags.Public | BindingFlags.Static| BindingFlags.IgnoreCase, null /*Binder*/, new Type[0], // Method with no parameters null ); } // Call the AppInitialize method if there is one internal void CallAppInitializeMethod() { if (_appInitializeMethod != null) { using (new ApplicationImpersonationContext()) { using (HostingEnvironment.SetCultures()) { _appInitializeMethod.Invoke(null, null); } } } } } /* * Same as BuildResultCompiledAssembly, but with some special behavior specific to * resources directory (both global and local) */ internal class BuildResultResourceAssembly : BuildResultCompiledAssembly { internal BuildResultResourceAssembly() { } internal BuildResultResourceAssembly(Assembly a) : base(a) { } internal override BuildResultTypeCode GetCode() { return BuildResultTypeCode.BuildResultResourceAssembly; } internal override string ComputeSourceDependenciesHashCode(VirtualPath virtualPath) { // If no virtual path was passed in, use the one from the BuildResult if (virtualPath == null) virtualPath = VirtualPath; // We don't want to use the default ComputeSourceDependenciesHashCode imnplementation, // as it would use all files in the resources dir to calculate the hash. Instead, // we only want the hash the be based on the culture neutral resources, so that // changes to culture specific files don't cause a rebuild of the main res assembly HashCodeCombiner hashCodeCombiner = new HashCodeCombiner(); hashCodeCombiner.AddResourcesDirectory(virtualPath.MapPathInternal()); return hashCodeCombiner.CombinedHashString; } // In addition to the standard BuildResult hash code (which drives recompilation of the main // resources assembly), we need an additional one so we know when to rebuild satellites. private string _resourcesDependenciesHash; internal string ResourcesDependenciesHash { get { EnsureResourcesDependenciesHashComputed(); return _resourcesDependenciesHash; } set { Debug.Assert(_resourcesDependenciesHash == null); _resourcesDependenciesHash = value; Debug.Assert(_resourcesDependenciesHash != null); } } private void EnsureResourcesDependenciesHashComputed() { if (_resourcesDependenciesHash != null) return; // Even though we make it dependent on all res files, if we get here we know the neutral // ones are up to date, so effectively it's look the culture specific that matter. _resourcesDependenciesHash = HashCodeCombiner.GetDirectoryHash(VirtualPath); } internal override void GetPreservedAttributes(PreservationFileReader pfr) { base.GetPreservedAttributes(pfr); ResourcesDependenciesHash = pfr.GetAttribute("resHash"); } internal override void SetPreservedAttributes(PreservationFileWriter pfw) { base.SetPreservedAttributes(pfw); pfw.SetAttribute("resHash", ResourcesDependenciesHash); } } internal class BuildResultCompiledType : BuildResultCompiledAssemblyBase, ITypedWebObjectFactory { // The delegate for fast object instantiation private InstantiateObject _instObj; private bool _triedToGetInstObj; internal BuildResultCompiledType() {} internal BuildResultCompiledType(Type t) { _builtType = t; } internal override BuildResultTypeCode GetCode() { return BuildResultTypeCode.BuildResultCompiledType; } internal override Assembly ResultAssembly { get { return _builtType.Assembly; } set { Debug.Assert(false); } } private Type _builtType; internal Type ResultType { get { return _builtType; } set { _builtType = value; } } // IWebObjectFactory.CreateInstance public object CreateInstance() { // Get the fast object creation delegate on demand if (!_triedToGetInstObj) { _instObj = ObjectFactoryCodeDomTreeGenerator.GetFastObjectCreationDelegate(ResultType); _triedToGetInstObj = true; } // If the fast factory is not available, just call CreateInstance // if (_instObj == null) { return HttpRuntime.CreatePublicInstance(ResultType); } // Call it to instantiate the object return _instObj(); } // ITypedWebObjectFactory.CreateInstance public virtual Type InstantiatedType { get { return ResultType; } } protected override void ComputeHashCode(HashCodeCombiner hashCodeCombiner) { base.ComputeHashCode(hashCodeCombiner); // Make pages have a dependency on the main local resources assembly, so that they // get recompiled when it changes (but not when satellites change). VSWhidbey 277357 if (VirtualPath != null) { // Remove the file name to get its directory VirtualPath virtualDir = VirtualPath.Parent; Assembly localResAssembly = BuildManager.GetLocalResourcesAssembly(virtualDir); if (localResAssembly != null) { hashCodeCombiner.AddFile(localResAssembly.Location); } } } internal override void GetPreservedAttributes(PreservationFileReader pfr) { base.GetPreservedAttributes(pfr); // Get the assembly and type Assembly a = GetPreservedAssembly(pfr); Debug.Assert(a != null); string typeName = pfr.GetAttribute("type"); ResultType = a.GetType(typeName, true /*throwOnError*/); } internal override void SetPreservedAttributes(PreservationFileWriter pfw) { base.SetPreservedAttributes(pfw); pfw.SetAttribute("type", ResultType.FullName); } } /* * Used for pages, user controls, and master pages */ internal class BuildResultCompiledTemplateType: BuildResultCompiledType { public BuildResultCompiledTemplateType() {} public BuildResultCompiledTemplateType(Type t) : base(t) {} internal override BuildResultTypeCode GetCode() { return BuildResultTypeCode.BuildResultCompiledTemplateType; } protected override void ComputeHashCode(HashCodeCombiner hashCodeCombiner) { base.ComputeHashCode(hashCodeCombiner); // Make the hash code depend on the relevant contents of the config section PagesSection pagesConfig = RuntimeConfig.GetConfig(VirtualPath).Pages; hashCodeCombiner.AddObject(Util.GetRecompilationHash(pagesConfig)); } } /* * Used for global.asax */ internal class BuildResultCompiledGlobalAsaxType : BuildResultCompiledType { public BuildResultCompiledGlobalAsaxType() { } public BuildResultCompiledGlobalAsaxType(Type t) : base(t) { } internal override BuildResultTypeCode GetCode() { return BuildResultTypeCode.BuildResultCompiledGlobalAsaxType; } // Does global.asax contain
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SystemUnicastIPAddressInformation.cs
- ConfigXmlElement.cs
- AutomationPatternInfo.cs
- WindowsToolbarItemAsMenuItem.cs
- SnapshotChangeTrackingStrategy.cs
- WebControlAdapter.cs
- ParameterModifier.cs
- CalendarDay.cs
- RoleService.cs
- TextRunProperties.cs
- EventlogProvider.cs
- Matrix3DStack.cs
- StrokeIntersection.cs
- VisualBrush.cs
- ToolboxItemFilterAttribute.cs
- XMLUtil.cs
- DatatypeImplementation.cs
- JournalEntry.cs
- SecurityDocument.cs
- ManifestBasedResourceGroveler.cs
- WebConvert.cs
- Control.cs
- DockProviderWrapper.cs
- SslStream.cs
- OleDbParameter.cs
- AngleUtil.cs
- ManagedFilter.cs
- MachineKeyConverter.cs
- ZipIOZip64EndOfCentralDirectoryBlock.cs
- AssertFilter.cs
- securitycriticaldataformultiplegetandset.cs
- MSG.cs
- DataTableTypeConverter.cs
- GridItemPattern.cs
- ReferencedAssembly.cs
- SqlFlattener.cs
- MemberMemberBinding.cs
- Win32PrintDialog.cs
- WebPartZone.cs
- CultureMapper.cs
- Encoder.cs
- RoutedEvent.cs
- EntityDataSourceWizardForm.cs
- clipboard.cs
- ApplicationActivator.cs
- DataTableTypeConverter.cs
- SettingsBindableAttribute.cs
- InternalControlCollection.cs
- SigningCredentials.cs
- SoapAttributes.cs
- StatusCommandUI.cs
- CultureMapper.cs
- PowerStatus.cs
- FileClassifier.cs
- TextTreeUndo.cs
- GeneralTransform3DGroup.cs
- Propagator.JoinPropagator.SubstitutingCloneVisitor.cs
- VirtualizingPanel.cs
- MetadataArtifactLoaderCompositeFile.cs
- RequestCache.cs
- ReadOnlyAttribute.cs
- ListSortDescription.cs
- Sql8ExpressionRewriter.cs
- SQlBooleanStorage.cs
- XmlLangPropertyAttribute.cs
- TypeDescriptionProviderAttribute.cs
- ScopeCompiler.cs
- TreeNodeCollectionEditorDialog.cs
- RequestCachingSection.cs
- MaskDescriptor.cs
- ToolStripPanel.cs
- RelatedPropertyManager.cs
- SubpageParaClient.cs
- ConstructorExpr.cs
- NetworkInformationException.cs
- Rect.cs
- ModifierKeysValueSerializer.cs
- TypedTableBase.cs
- TextPatternIdentifiers.cs
- EmptyCollection.cs
- StorageEntitySetMapping.cs
- SQLInt64Storage.cs
- PrintPageEvent.cs
- DeleteWorkflowOwnerCommand.cs
- ThemeDirectoryCompiler.cs
- XmlElementAttributes.cs
- Ray3DHitTestResult.cs
- SQLRoleProvider.cs
- HashFinalRequest.cs
- XmlSerializerSection.cs
- TextEditorThreadLocalStore.cs
- SqlFactory.cs
- EventProviderWriter.cs
- Message.cs
- DataPagerFieldItem.cs
- SimpleApplicationHost.cs
- Rfc4050KeyFormatter.cs
- HtmlString.cs
- Hash.cs
- PointAnimationUsingKeyFrames.cs