Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Metadata / ObjectLayer / AssemblyCache.cs / 1305376 / AssemblyCache.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Collections.Generic; using System.Data.Common.Utils; using System.Diagnostics; using System.Reflection; namespace System.Data.Metadata.Edm { internal static class AssemblyCache { // Global Assembly Cache private readonly static Dictionarys_globalAssemblyCache = new Dictionary (); private static object _assemblyCacheLock = new object(); //List of assemblies having view gen attribute. We cache these things if we discover //these assemblies while looking for O-space metadata. private static IList s_viewGenAssemblies = new ThreadSafeList (); internal static LockedAssemblyCache AquireLockedAssemblyCache() { return new LockedAssemblyCache(_assemblyCacheLock, s_globalAssemblyCache); } internal static void LoadAssembly(Assembly assembly, bool loadReferencedAssemblies, KnownAssembliesSet knownAssemblies, out Dictionary typesInLoading, out List errors) { object loaderCookie = null; LoadAssembly(assembly, loadReferencedAssemblies, knownAssemblies, null, null, ref loaderCookie, out typesInLoading, out errors); } internal static void LoadAssembly(Assembly assembly, bool loadReferencedAssemblies, KnownAssembliesSet knownAssemblies, EdmItemCollection edmItemCollection, Action logLoadMessage, ref object loaderCookie, out Dictionary typesInLoading, out List errors) { Debug.Assert(loaderCookie == null || loaderCookie is Func , "This is a bad loader cookie"); typesInLoading = null; errors = null; using (LockedAssemblyCache lockedAssemblyCache = AssemblyCache.AquireLockedAssemblyCache()) { ObjectItemLoadingSessionData loadingData = new ObjectItemLoadingSessionData(knownAssemblies, lockedAssemblyCache, edmItemCollection, logLoadMessage, loaderCookie); LoadAssembly(assembly, loadReferencedAssemblies, loadingData); loaderCookie = loadingData.LoaderCookie; // resolve references to top level types (base types, navigation properties returns and associations, and complex type properties) loadingData.CompleteSession(); if (loadingData.EdmItemErrors.Count == 0) { // do the validation for the all the new types // Now, perform validation on all the new types EdmValidator validator = new EdmValidator(); validator.SkipReadOnlyItems = true; validator.Validate(loadingData.TypesInLoading.Values, loadingData.EdmItemErrors); // Update the global cache if there are no errors if (loadingData.EdmItemErrors.Count == 0) { if (ObjectItemAssemblyLoader.IsAttributeLoader(loadingData.ObjectItemAssemblyLoaderFactory)) { // we only cache items from the attribute loader globally, the // items loaded by convention will change depending on the cspace // provided. cspace will have a cache of it's own for assemblies UpdateCache(lockedAssemblyCache, loadingData.AssembliesLoaded); } else if (loadingData.EdmItemCollection != null && ObjectItemAssemblyLoader.IsConventionLoader(loadingData.ObjectItemAssemblyLoaderFactory)) { UpdateCache(loadingData.EdmItemCollection, loadingData.AssembliesLoaded); } } } if (loadingData.TypesInLoading.Count > 0) { foreach (EdmType edmType in loadingData.TypesInLoading.Values) { edmType.SetReadOnly(); } } // Update the out parameters once you are done with loading typesInLoading = loadingData.TypesInLoading; errors = loadingData.EdmItemErrors; } } private static void LoadAssembly(Assembly assembly, bool loadReferencedAssemblies, ObjectItemLoadingSessionData loadingData) { // Check if the assembly is already loaded KnownAssemblyEntry entry; bool shouldLoadReferences = false; if (loadingData.KnownAssemblies.TryGetKnownAssembly(assembly, loadingData.ObjectItemAssemblyLoaderFactory, loadingData.EdmItemCollection, out entry)) { shouldLoadReferences = !entry.ReferencedAssembliesAreLoaded && loadReferencedAssemblies; } else { ObjectItemAssemblyLoader loader = ObjectItemAssemblyLoader.CreateLoader(assembly, loadingData); loader.Load(); shouldLoadReferences = loadReferencedAssemblies; } if (shouldLoadReferences) { if (entry == null && loadingData.KnownAssemblies.TryGetKnownAssembly(assembly, loadingData.ObjectItemAssemblyLoaderFactory, loadingData.EdmItemCollection, out entry) || entry != null) { entry.ReferencedAssembliesAreLoaded = true; } Debug.Assert(entry != null, "we should always have an entry, why don't we?"); // We will traverse through all the statically linked assemblies and their dependencies. // Only assemblies with the EdmSchemaAttribute will be loaded and rest will be ignored // Even if the schema attribute is missing, we should still check all the dependent assemblies // any of the dependent assemblies can have the schema attribute // After the given assembly has been loaded, check on the flag in _knownAssemblies to see if it has already // been recursively loaded. The flag can be true if it was already loaded before this function was called foreach (Assembly referencedAssembly in MetadataAssemblyHelper.GetNonSystemReferencedAssemblies(assembly)) { // filter out "known" assemblies to prevent unnecessary loading EntityBid.Trace(" loadededAssembly='%ls'\n", referencedAssembly.FullName); // recursive call LoadAssembly(referencedAssembly, loadReferencedAssemblies, loadingData); } } } private static void UpdateCache(EdmItemCollection edmItemCollection, Dictionary assemblies) { foreach (var entry in assemblies) { edmItemCollection.ConventionalOcCache.AddAssemblyToOcCacheFromAssemblyCache( entry.Key, new ImmutableAssemblyCacheEntry(entry.Value)); } } private static void UpdateCache(LockedAssemblyCache lockedAssemblyCache, Dictionary assemblies) { foreach (KeyValuePair entry in assemblies) { // Add all the assemblies from the loading context to the global cache lockedAssemblyCache.Add(entry.Key, new ImmutableAssemblyCacheEntry(entry.Value)); } } internal static IList ViewGenerationAssemblies { get { return s_viewGenAssemblies; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Collections.Generic; using System.Data.Common.Utils; using System.Diagnostics; using System.Reflection; namespace System.Data.Metadata.Edm { internal static class AssemblyCache { // Global Assembly Cache private readonly static Dictionarys_globalAssemblyCache = new Dictionary (); private static object _assemblyCacheLock = new object(); //List of assemblies having view gen attribute. We cache these things if we discover //these assemblies while looking for O-space metadata. private static IList s_viewGenAssemblies = new ThreadSafeList (); internal static LockedAssemblyCache AquireLockedAssemblyCache() { return new LockedAssemblyCache(_assemblyCacheLock, s_globalAssemblyCache); } internal static void LoadAssembly(Assembly assembly, bool loadReferencedAssemblies, KnownAssembliesSet knownAssemblies, out Dictionary typesInLoading, out List errors) { object loaderCookie = null; LoadAssembly(assembly, loadReferencedAssemblies, knownAssemblies, null, null, ref loaderCookie, out typesInLoading, out errors); } internal static void LoadAssembly(Assembly assembly, bool loadReferencedAssemblies, KnownAssembliesSet knownAssemblies, EdmItemCollection edmItemCollection, Action logLoadMessage, ref object loaderCookie, out Dictionary typesInLoading, out List errors) { Debug.Assert(loaderCookie == null || loaderCookie is Func , "This is a bad loader cookie"); typesInLoading = null; errors = null; using (LockedAssemblyCache lockedAssemblyCache = AssemblyCache.AquireLockedAssemblyCache()) { ObjectItemLoadingSessionData loadingData = new ObjectItemLoadingSessionData(knownAssemblies, lockedAssemblyCache, edmItemCollection, logLoadMessage, loaderCookie); LoadAssembly(assembly, loadReferencedAssemblies, loadingData); loaderCookie = loadingData.LoaderCookie; // resolve references to top level types (base types, navigation properties returns and associations, and complex type properties) loadingData.CompleteSession(); if (loadingData.EdmItemErrors.Count == 0) { // do the validation for the all the new types // Now, perform validation on all the new types EdmValidator validator = new EdmValidator(); validator.SkipReadOnlyItems = true; validator.Validate(loadingData.TypesInLoading.Values, loadingData.EdmItemErrors); // Update the global cache if there are no errors if (loadingData.EdmItemErrors.Count == 0) { if (ObjectItemAssemblyLoader.IsAttributeLoader(loadingData.ObjectItemAssemblyLoaderFactory)) { // we only cache items from the attribute loader globally, the // items loaded by convention will change depending on the cspace // provided. cspace will have a cache of it's own for assemblies UpdateCache(lockedAssemblyCache, loadingData.AssembliesLoaded); } else if (loadingData.EdmItemCollection != null && ObjectItemAssemblyLoader.IsConventionLoader(loadingData.ObjectItemAssemblyLoaderFactory)) { UpdateCache(loadingData.EdmItemCollection, loadingData.AssembliesLoaded); } } } if (loadingData.TypesInLoading.Count > 0) { foreach (EdmType edmType in loadingData.TypesInLoading.Values) { edmType.SetReadOnly(); } } // Update the out parameters once you are done with loading typesInLoading = loadingData.TypesInLoading; errors = loadingData.EdmItemErrors; } } private static void LoadAssembly(Assembly assembly, bool loadReferencedAssemblies, ObjectItemLoadingSessionData loadingData) { // Check if the assembly is already loaded KnownAssemblyEntry entry; bool shouldLoadReferences = false; if (loadingData.KnownAssemblies.TryGetKnownAssembly(assembly, loadingData.ObjectItemAssemblyLoaderFactory, loadingData.EdmItemCollection, out entry)) { shouldLoadReferences = !entry.ReferencedAssembliesAreLoaded && loadReferencedAssemblies; } else { ObjectItemAssemblyLoader loader = ObjectItemAssemblyLoader.CreateLoader(assembly, loadingData); loader.Load(); shouldLoadReferences = loadReferencedAssemblies; } if (shouldLoadReferences) { if (entry == null && loadingData.KnownAssemblies.TryGetKnownAssembly(assembly, loadingData.ObjectItemAssemblyLoaderFactory, loadingData.EdmItemCollection, out entry) || entry != null) { entry.ReferencedAssembliesAreLoaded = true; } Debug.Assert(entry != null, "we should always have an entry, why don't we?"); // We will traverse through all the statically linked assemblies and their dependencies. // Only assemblies with the EdmSchemaAttribute will be loaded and rest will be ignored // Even if the schema attribute is missing, we should still check all the dependent assemblies // any of the dependent assemblies can have the schema attribute // After the given assembly has been loaded, check on the flag in _knownAssemblies to see if it has already // been recursively loaded. The flag can be true if it was already loaded before this function was called foreach (Assembly referencedAssembly in MetadataAssemblyHelper.GetNonSystemReferencedAssemblies(assembly)) { // filter out "known" assemblies to prevent unnecessary loading EntityBid.Trace(" loadededAssembly='%ls'\n", referencedAssembly.FullName); // recursive call LoadAssembly(referencedAssembly, loadReferencedAssemblies, loadingData); } } } private static void UpdateCache(EdmItemCollection edmItemCollection, Dictionary assemblies) { foreach (var entry in assemblies) { edmItemCollection.ConventionalOcCache.AddAssemblyToOcCacheFromAssemblyCache( entry.Key, new ImmutableAssemblyCacheEntry(entry.Value)); } } private static void UpdateCache(LockedAssemblyCache lockedAssemblyCache, Dictionary assemblies) { foreach (KeyValuePair entry in assemblies) { // Add all the assemblies from the loading context to the global cache lockedAssemblyCache.Add(entry.Key, new ImmutableAssemblyCacheEntry(entry.Value)); } } internal static IList ViewGenerationAssemblies { get { return s_viewGenAssemblies; } } } } // 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
- versioninfo.cs
- SecurityDescriptor.cs
- Security.cs
- ConnectionManagementElement.cs
- HtmlElementCollection.cs
- DataGridViewCheckBoxCell.cs
- TerminatorSinks.cs
- ToolStripDropDownClosingEventArgs.cs
- LongMinMaxAggregationOperator.cs
- HttpProfileBase.cs
- Peer.cs
- FamilyCollection.cs
- StringAnimationBase.cs
- XPathSelectionIterator.cs
- ISAPIWorkerRequest.cs
- mongolianshape.cs
- SuppressMessageAttribute.cs
- KeyPullup.cs
- Quaternion.cs
- ClientScriptManager.cs
- DataGridCommandEventArgs.cs
- DateTimeFormatInfo.cs
- WebPartHeaderCloseVerb.cs
- ExecutorLocksHeldException.cs
- InheritanceContextHelper.cs
- WsatExtendedInformation.cs
- CryptoProvider.cs
- BitmapImage.cs
- AnchorEditor.cs
- DateTimeConverter2.cs
- ToolStripSplitStackLayout.cs
- GridViewHeaderRowPresenter.cs
- PasswordTextNavigator.cs
- BmpBitmapDecoder.cs
- _CacheStreams.cs
- RegistryExceptionHelper.cs
- EventProvider.cs
- PeerNameRecord.cs
- ResXResourceWriter.cs
- UserControlParser.cs
- ActivityTypeCodeDomSerializer.cs
- ColorConverter.cs
- TextFragmentEngine.cs
- FixedTextPointer.cs
- ProjectionPathSegment.cs
- WindowAutomationPeer.cs
- CommonRemoteMemoryBlock.cs
- SchemaDeclBase.cs
- X509Logo.cs
- XmlSignatureProperties.cs
- MetafileHeader.cs
- QuotaExceededException.cs
- OutputCacheSection.cs
- FontCollection.cs
- sapiproxy.cs
- DBCSCodePageEncoding.cs
- EUCJPEncoding.cs
- XmlIlVisitor.cs
- PerformanceCounterPermissionEntry.cs
- SimpleType.cs
- ResourcePool.cs
- SBCSCodePageEncoding.cs
- TraceHandler.cs
- CopyAction.cs
- X509RecipientCertificateClientElement.cs
- DataGridViewColumnEventArgs.cs
- sqlser.cs
- ThreadAbortException.cs
- ImplicitInputBrush.cs
- autovalidator.cs
- RadialGradientBrush.cs
- BorderGapMaskConverter.cs
- DataContext.cs
- ConsoleTraceListener.cs
- BindingEntityInfo.cs
- PathSegmentCollection.cs
- SchemaImporterExtension.cs
- DependencyPropertyValueSerializer.cs
- SourceFilter.cs
- RadioButton.cs
- AutomationPropertyInfo.cs
- TextParagraphProperties.cs
- UIElement.cs
- SelectingProviderEventArgs.cs
- TypeUsage.cs
- MetadataSerializer.cs
- XPathEmptyIterator.cs
- CellParagraph.cs
- RSAPKCS1SignatureDeformatter.cs
- DeferredElementTreeState.cs
- TableRowGroupCollection.cs
- DesignerAttribute.cs
- SR.Designer.cs
- Path.cs
- CancelRequestedQuery.cs
- Itemizer.cs
- RotateTransform.cs
- ConfigurationStrings.cs
- MatrixAnimationBase.cs
- XmlEventCache.cs