internal static void LoadAssembly( Assembly assembly, bool loadReferencedAssemblies, KnownAssembliesSet knownAssemblies, out Dictionary<string, EdmType> typesInLoading, out List<EdmItemError> 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<String> logLoadMessage, ref object loaderCookie, out Dictionary<string, EdmType> typesInLoading, out List<EdmItemError> errors) { Debug.Assert( loaderCookie == null || loaderCookie is Func<Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>, "This is a bad loader cookie"); typesInLoading = null; errors = null; using (var lockedAssemblyCache = AquireLockedAssemblyCache()) { var 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 var 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 (var edmType in loadingData.TypesInLoading.Values) { edmType.SetReadOnly(); } } // Update the out parameters once you are done with loading typesInLoading = loadingData.TypesInLoading; errors = loadingData.EdmItemErrors; } }
internal static void LoadAssembly( Assembly assembly, bool loadReferencedAssemblies, KnownAssembliesSet knownAssemblies, EdmItemCollection edmItemCollection, Action <String> logLoadMessage, ref object loaderCookie, out Dictionary <string, EdmType> typesInLoading, out List <EdmItemError> errors) { Debug.Assert( loaderCookie == null || loaderCookie is Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>, "This is a bad loader cookie"); typesInLoading = null; errors = null; using (var lockedAssemblyCache = AquireLockedAssemblyCache()) { var 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 var 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 (var edmType in loadingData.TypesInLoading.Values) { edmType.SetReadOnly(); } } // Update the out parameters once you are done with loading typesInLoading = loadingData.TypesInLoading; errors = loadingData.EdmItemErrors; } }
internal static void LoadAssembly( Assembly assembly, bool loadReferencedAssemblies, KnownAssembliesSet knownAssemblies, out Dictionary <string, EdmType> typesInLoading, out List <EdmItemError> errors) { object loaderCookie = null; LoadAssembly(assembly, loadReferencedAssemblies, knownAssemblies, null, null, ref loaderCookie, out typesInLoading, out errors); }
internal ObjectItemCollection(KnownAssembliesSet knownAssembliesSet = null) : base(DataSpace.OSpace) { this._knownAssemblies = knownAssembliesSet ?? new KnownAssembliesSet(); foreach (PrimitiveType storeType in ClrProviderManifest.Instance.GetStoreTypes()) { this.AddInternal((GlobalItem)storeType); this._primitiveTypeMaps.Add(storeType); } }
internal ObjectItemCollection(KnownAssembliesSet knownAssembliesSet = null) : base(DataSpace.OSpace) { _knownAssemblies = knownAssembliesSet ?? new KnownAssembliesSet(); foreach (var type in ClrProviderManifest.Instance.GetStoreTypes()) { AddInternal(type); _primitiveTypeMaps.Add(type); } }
internal ObjectItemCollection(IViewAssemblyCache viewAssemblyCache, KnownAssembliesSet knownAssembliesSet = null) : base(DataSpace.OSpace) { _viewAssemblyCache = viewAssemblyCache ?? DbConfiguration.GetService <IViewAssemblyCache>(); _knownAssemblies = knownAssembliesSet ?? new KnownAssembliesSet(); foreach (var type in ClrProviderManifest.Instance.GetStoreTypes()) { AddInternal(type); _primitiveTypeMaps.Add(type); } }
public virtual Dictionary <string, EdmType> LoadTypesExpensiveWay( Assembly assembly) { KnownAssembliesSet knownAssemblies = new KnownAssembliesSet(); Dictionary <string, EdmType> typesInLoading; List <EdmItemError> errors; AssemblyCache.LoadAssembly(assembly, false, knownAssemblies, out typesInLoading, out errors); if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage((IEnumerable <EdmItemError>)errors)); } return(typesInLoading); }
internal ObjectItemLoadingSessionData( KnownAssembliesSet knownAssemblies, LockedAssemblyCache lockedAssemblyCache, EdmItemCollection edmItemCollection, Action <String> logLoadMessage, object loaderCookie) { Debug.Assert( loaderCookie == null || loaderCookie is Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>, "This is a bad loader cookie"); _typesInLoading = new Dictionary <string, EdmType>(StringComparer.Ordinal); _errors = new List <EdmItemError>(); _knownAssemblies = knownAssemblies; _lockedAssemblyCache = lockedAssemblyCache; _loadersThatNeedLevel1PostSessionProcessing = new HashSet <ObjectItemAssemblyLoader>(); _loadersThatNeedLevel2PostSessionProcessing = new HashSet <ObjectItemAssemblyLoader>(); _edmItemCollection = edmItemCollection; _loadMessageLogger = new LoadMessageLogger(logLoadMessage); _cspaceToOspace = new Dictionary <EdmType, EdmType>(); _loaderFactory = (Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>)loaderCookie; _originalLoaderCookie = loaderCookie; if (_loaderFactory == ObjectItemConventionAssemblyLoader.Create && _edmItemCollection != null) { foreach (var entry in _knownAssemblies.GetEntries(_loaderFactory, edmItemCollection)) { foreach (var type in entry.CacheEntry.TypesInAssembly.OfType <EdmType>()) { if (Helper.IsEntityType(type)) { var entityType = (ClrEntityType)type; _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(entityType.CSpaceTypeName), entityType); } else if (Helper.IsComplexType(type)) { var complexType = (ClrComplexType)type; _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(complexType.CSpaceTypeName), complexType); } else if (Helper.IsEnumType(type)) { var enumType = (ClrEnumType)type; _cspaceToOspace.Add(_edmItemCollection.GetItem <EnumType>(enumType.CSpaceTypeName), enumType); } else { Debug.Assert(Helper.IsAssociationType(type)); _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(type.FullName), type); } } } } }
internal static void LoadAssembly( Assembly assembly, bool loadReferencedAssemblies, KnownAssembliesSet knownAssemblies, EdmItemCollection edmItemCollection, Action <string> logLoadMessage, ref object loaderCookie, out Dictionary <string, EdmType> typesInLoading, out List <EdmItemError> errors) { typesInLoading = (Dictionary <string, EdmType>)null; errors = (List <EdmItemError>)null; using (LockedAssemblyCache lockedAssemblyCache = AssemblyCache.AquireLockedAssemblyCache()) { ObjectItemLoadingSessionData loadingData = new ObjectItemLoadingSessionData(knownAssemblies, lockedAssemblyCache, edmItemCollection, logLoadMessage, loaderCookie); AssemblyCache.LoadAssembly(assembly, loadReferencedAssemblies, loadingData); loaderCookie = loadingData.LoaderCookie; loadingData.CompleteSession(); if (loadingData.EdmItemErrors.Count == 0) { new EdmValidator() { SkipReadOnlyItems = true }.Validate <EdmType>((IEnumerable <EdmType>)loadingData.TypesInLoading.Values, loadingData.EdmItemErrors); if (loadingData.EdmItemErrors.Count == 0) { if (ObjectItemAssemblyLoader.IsAttributeLoader(loadingData.ObjectItemAssemblyLoaderFactory)) { AssemblyCache.UpdateCache(lockedAssemblyCache, loadingData.AssembliesLoaded); } else if (loadingData.EdmItemCollection != null && ObjectItemAssemblyLoader.IsConventionLoader(loadingData.ObjectItemAssemblyLoaderFactory)) { AssemblyCache.UpdateCache(loadingData.EdmItemCollection, loadingData.AssembliesLoaded); } } } if (loadingData.TypesInLoading.Count > 0) { foreach (MetadataItem metadataItem in loadingData.TypesInLoading.Values) { metadataItem.SetReadOnly(); } } typesInLoading = loadingData.TypesInLoading; errors = loadingData.EdmItemErrors; } }
internal ObjectItemLoadingSessionData( KnownAssembliesSet knownAssemblies, LockedAssemblyCache lockedAssemblyCache, EdmItemCollection edmItemCollection, Action <string> logLoadMessage, object loaderCookie) { this._typesInLoading = new Dictionary <string, EdmType>((IEqualityComparer <string>)StringComparer.Ordinal); this._errors = new List <EdmItemError>(); this._knownAssemblies = knownAssemblies; this._lockedAssemblyCache = lockedAssemblyCache; this._edmItemCollection = edmItemCollection; this._loadMessageLogger = new LoadMessageLogger(logLoadMessage); this._cspaceToOspace = new Dictionary <EdmType, EdmType>(); this._loaderFactory = (Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>)loaderCookie; this._originalLoaderCookie = loaderCookie; if (!(this._loaderFactory == new Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>(ObjectItemConventionAssemblyLoader.Create)) || this._edmItemCollection == null) { return; } foreach (KnownAssemblyEntry entry in this._knownAssemblies.GetEntries((object)this._loaderFactory, edmItemCollection)) { foreach (EdmType edmType in entry.CacheEntry.TypesInAssembly.OfType <EdmType>()) { if (Helper.IsEntityType(edmType)) { ClrEntityType clrEntityType = (ClrEntityType)edmType; this._cspaceToOspace.Add((EdmType)this._edmItemCollection.GetItem <StructuralType>(clrEntityType.CSpaceTypeName), (EdmType)clrEntityType); } else if (Helper.IsComplexType(edmType)) { ClrComplexType clrComplexType = (ClrComplexType)edmType; this._cspaceToOspace.Add((EdmType)this._edmItemCollection.GetItem <StructuralType>(clrComplexType.CSpaceTypeName), (EdmType)clrComplexType); } else if (Helper.IsEnumType(edmType)) { ClrEnumType clrEnumType = (ClrEnumType)edmType; this._cspaceToOspace.Add((EdmType)this._edmItemCollection.GetItem <EnumType>(clrEnumType.CSpaceTypeName), (EdmType)clrEnumType); } else { this._cspaceToOspace.Add((EdmType)this._edmItemCollection.GetItem <StructuralType>(edmType.FullName), edmType); } } } }
/// <summary> /// Loads the OSpace types in the assembly and returns them as a dictionary /// </summary> /// <param name="assembly"> The assembly to load </param> /// <returns> A mapping from names to OSpace EdmTypes </returns> internal static Dictionary <string, EdmType> LoadTypesExpensiveWay(Assembly assembly) { Dictionary <string, EdmType> typesInLoading = null; List <EdmItemError> errors; var knownAssemblies = new KnownAssembliesSet(); AssemblyCache.LoadAssembly( assembly, false /*loadAllReferencedAssemblies*/, knownAssemblies, out typesInLoading, out errors); // Check for errors if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errors)); } return(typesInLoading); }
public virtual Dictionary<string, EdmType> LoadTypesExpensiveWay(Assembly assembly) { DebugCheck.NotNull(assembly); Dictionary<string, EdmType> typesInLoading; List<EdmItemError> errors; var knownAssemblies = new KnownAssembliesSet(); AssemblyCache.LoadAssembly( assembly, false /*loadAllReferencedAssemblies*/, knownAssemblies, out typesInLoading, out errors); // Check for errors if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errors)); } return typesInLoading; }
internal ObjectItemLoadingSessionData( KnownAssembliesSet knownAssemblies, LockedAssemblyCache lockedAssemblyCache, EdmItemCollection edmItemCollection, Action<String> logLoadMessage, object loaderCookie) { Debug.Assert( loaderCookie == null || loaderCookie is Func<Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>, "This is a bad loader cookie"); _typesInLoading = new Dictionary<string, EdmType>(StringComparer.Ordinal); _errors = new List<EdmItemError>(); _knownAssemblies = knownAssemblies; _lockedAssemblyCache = lockedAssemblyCache; _loadersThatNeedLevel1PostSessionProcessing = new HashSet<ObjectItemAssemblyLoader>(); _loadersThatNeedLevel2PostSessionProcessing = new HashSet<ObjectItemAssemblyLoader>(); _edmItemCollection = edmItemCollection; _loadMessageLogger = new LoadMessageLogger(logLoadMessage); _cspaceToOspace = new Dictionary<EdmType, EdmType>(); _loaderFactory = (Func<Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>)loaderCookie; _originalLoaderCookie = loaderCookie; if (_loaderFactory == ObjectItemConventionAssemblyLoader.Create && _edmItemCollection != null) { foreach (var entry in _knownAssemblies.GetEntries(_loaderFactory, edmItemCollection)) { foreach (var type in entry.CacheEntry.TypesInAssembly.OfType<EdmType>()) { if (Helper.IsEntityType(type)) { var entityType = (ClrEntityType)type; _cspaceToOspace.Add(_edmItemCollection.GetItem<StructuralType>(entityType.CSpaceTypeName), entityType); } else if (Helper.IsComplexType(type)) { var complexType = (ClrComplexType)type; _cspaceToOspace.Add(_edmItemCollection.GetItem<StructuralType>(complexType.CSpaceTypeName), complexType); } else if (Helper.IsEnumType(type)) { var enumType = (ClrEnumType)type; _cspaceToOspace.Add(_edmItemCollection.GetItem<EnumType>(enumType.CSpaceTypeName), enumType); } else { Debug.Assert(Helper.IsAssociationType(type)); _cspaceToOspace.Add(_edmItemCollection.GetItem<StructuralType>(type.FullName), type); } } } } }
internal KnownAssembliesSet(KnownAssembliesSet set) { _assemblies = new Dictionary<Assembly, KnownAssemblyEntry>(set._assemblies); }
internal KnownAssembliesSet(KnownAssembliesSet set) { _assemblies = new Dictionary <Assembly, KnownAssemblyEntry>(set._assemblies); }
private bool LoadAssemblyFromCache( Assembly assembly, bool loadReferencedAssemblies, EdmItemCollection edmItemCollection, Action <String> logLoadMessage) { _viewAssemblyCache.CheckAssembly(assembly, loadReferencedAssemblies); // Code First already did type loading if (OSpaceTypesLoaded) { return(true); } // Check if its loaded in the cache - if the call is for loading referenced assemblies, make sure that all referenced // assemblies are also loaded KnownAssemblyEntry entry; if (_knownAssemblies.TryGetKnownAssembly(assembly, _loaderCookie, edmItemCollection, out entry)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false) { // don't say we loaded anything, unless we actually did before return(entry.CacheEntry.TypesInAssembly.Count != 0); } else if (entry.ReferencedAssembliesAreLoaded) { // this assembly was part of a all hands reference search return(true); } } lock (LoadAssemblyLock) { // Check after acquiring the lock, since the known assemblies might have got modified // Check if the assembly is already loaded. The reason we need to check if the assembly is already loaded, is that if (_knownAssemblies.TryGetKnownAssembly(assembly, _loaderCookie, edmItemCollection, out entry)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false || entry.ReferencedAssembliesAreLoaded) { return(true); } } Dictionary <string, EdmType> typesInLoading; List <EdmItemError> errors; var knownAssemblies = new KnownAssembliesSet(_knownAssemblies); // Load the assembly from the cache AssemblyCache.LoadAssembly( assembly, loadReferencedAssemblies, knownAssemblies, edmItemCollection, logLoadMessage, ref _loaderCookie, out typesInLoading, out errors); // Throw if we have encountered errors if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errors)); } // We can encounter new assemblies, but they may not have any time in them if (typesInLoading.Count != 0) { // No errors, so go ahead and add the types and make them readonly // The existence of the loading lock tells us whether we should be thread safe or not, if we need // to be thread safe, then we need to use AtomicAddRange. We don't need to actually use the lock // because the caller should have done it already // Recheck the assemblies added, another list is created just to match up the collection type // taken in by AtomicAddRange() AddLoadedTypes(typesInLoading); } // Update the value of known assemblies _knownAssemblies = knownAssemblies; return(typesInLoading.Count != 0); } }
private bool LoadAssemblyFromCache( Assembly assembly, bool loadReferencedAssemblies, EdmItemCollection edmItemCollection, Action <string> logLoadMessage) { if (this.OSpaceTypesLoaded) { return(true); } if (edmItemCollection != null) { ReadOnlyCollection <EntityContainer> items = edmItemCollection.GetItems <EntityContainer>(); if (items.Any <EntityContainer>() && items.All <EntityContainer>((Func <EntityContainer, bool>)(c => c.Annotations.Any <MetadataProperty>((Func <MetadataProperty, bool>)(a => { if (a.Name == "http://schemas.microsoft.com/ado/2013/11/edm/customannotation:UseClrTypes") { return(((string)a.Value).ToUpperInvariant() == "TRUE"); } return(false); }))))) { lock (this.LoadAssemblyLock) { if (!this.OSpaceTypesLoaded) { new CodeFirstOSpaceLoader((CodeFirstOSpaceTypeFactory)null).LoadTypes(edmItemCollection, this); } return(true); } } } KnownAssemblyEntry entry; if (this._knownAssemblies.TryGetKnownAssembly(assembly, this._loaderCookie, edmItemCollection, out entry)) { if (!loadReferencedAssemblies) { return(entry.CacheEntry.TypesInAssembly.Count != 0); } if (entry.ReferencedAssembliesAreLoaded) { return(true); } } lock (this.LoadAssemblyLock) { if (this._knownAssemblies.TryGetKnownAssembly(assembly, this._loaderCookie, edmItemCollection, out entry) && (!loadReferencedAssemblies || entry.ReferencedAssembliesAreLoaded)) { return(true); } KnownAssembliesSet knownAssemblies = new KnownAssembliesSet(this._knownAssemblies); Dictionary <string, EdmType> typesInLoading; List <EdmItemError> errors; AssemblyCache.LoadAssembly(assembly, loadReferencedAssemblies, knownAssemblies, edmItemCollection, logLoadMessage, ref this._loaderCookie, out typesInLoading, out errors); if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage((IEnumerable <EdmItemError>)errors)); } if (typesInLoading.Count != 0) { this.AddLoadedTypes(typesInLoading); } this._knownAssemblies = knownAssemblies; return(typesInLoading.Count != 0); } }
private static bool LoadAssemblyFromCache( ObjectItemCollection objectItemCollection, Assembly assembly, bool loadReferencedAssemblies, EdmItemCollection edmItemCollection, Action <String> logLoadMessage) { // Check if its loaded in the cache - if the call is for loading referenced assemblies, make sure that all referenced // assemblies are also loaded KnownAssemblyEntry entry; if (objectItemCollection._knownAssemblies.TryGetKnownAssembly( assembly, objectItemCollection._loaderCookie, edmItemCollection, out entry)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false) { // don't say we loaded anything, unless we actually did before return(entry.CacheEntry.TypesInAssembly.Count != 0); } else if (entry.ReferencedAssembliesAreLoaded) { // this assembly was part of a all hands reference search return(true); } } lock (objectItemCollection.LoadAssemblyLock) { // Check after acquiring the lock, since the known assemblies might have got modified // Check if the assembly is already loaded. The reason we need to check if the assembly is already loaded, is that if (objectItemCollection._knownAssemblies.TryGetKnownAssembly( assembly, objectItemCollection._loaderCookie, edmItemCollection, out entry)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false || entry.ReferencedAssembliesAreLoaded) { return(true); } } Dictionary <string, EdmType> typesInLoading; List <EdmItemError> errors; KnownAssembliesSet knownAssemblies; if (objectItemCollection != null) { knownAssemblies = new KnownAssembliesSet(objectItemCollection._knownAssemblies); } else { knownAssemblies = new KnownAssembliesSet(); } // Load the assembly from the cache AssemblyCache.LoadAssembly( assembly, loadReferencedAssemblies, knownAssemblies, edmItemCollection, logLoadMessage, ref objectItemCollection._loaderCookie, out typesInLoading, out errors); // Throw if we have encountered errors if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errors)); } // We can encounter new assemblies, but they may not have any time in them if (typesInLoading.Count != 0) { // No errors, so go ahead and add the types and make them readonly // The existence of the loading lock tells us whether we should be thread safe or not, if we need // to be thread safe, then we need to use AtomicAddRange. We don't need to actually use the lock // because the caller should have done it already // Recheck the assemblies added, another list is created just to match up the collection type // taken in by AtomicAddRange() var globalItems = new List <GlobalItem>(); foreach (var edmType in typesInLoading.Values) { globalItems.Add(edmType); var cspaceTypeName = ""; try { // Also populate the ocmapping information if (Helper.IsEntityType(edmType)) { cspaceTypeName = ((ClrEntityType)edmType).CSpaceTypeName; objectItemCollection._ocMapping.Add(cspaceTypeName, edmType); } else if (Helper.IsComplexType(edmType)) { cspaceTypeName = ((ClrComplexType)edmType).CSpaceTypeName; objectItemCollection._ocMapping.Add(cspaceTypeName, edmType); } else if (Helper.IsEnumType(edmType)) { cspaceTypeName = ((ClrEnumType)edmType).CSpaceTypeName; objectItemCollection._ocMapping.Add(cspaceTypeName, edmType); } // for the rest of the types like a relationship type, we do not have oc mapping, // so we don't keep that information } catch (ArgumentException e) { throw new MappingException(Strings.Mapping_CannotMapCLRTypeMultipleTimes(cspaceTypeName), e); } } // Create a new ObjectItemCollection and add all the global items to it. // Also copy all the existing items from the existing collection objectItemCollection.AtomicAddRange(globalItems); } // Update the value of known assemblies objectItemCollection._knownAssemblies = knownAssemblies; foreach (var loadedAssembly in knownAssemblies.Assemblies) { CollectIfViewGenAssembly(loadedAssembly); } return(typesInLoading.Count != 0); } }
private bool LoadAssemblyFromCache( Assembly assembly, bool loadReferencedAssemblies, EdmItemCollection edmItemCollection, Action <String> logLoadMessage) { // Code First already did type loading if (OSpaceTypesLoaded) { return(true); } // If all the containers (usually only one) have the UseClrTypes annotation then use the Code First loader even // when using an EDMX. if (edmItemCollection != null) { var containers = edmItemCollection.GetItems <EntityContainer>(); if (containers.Any() && containers.All( c => c.Annotations.Any( a => a.Name == XmlConstants.UseClrTypesAnnotationWithPrefix && ((string)a.Value).ToUpperInvariant() == "TRUE"))) { lock (LoadAssemblyLock) { if (!OSpaceTypesLoaded) { new CodeFirstOSpaceLoader().LoadTypes(edmItemCollection, this); Debug.Assert(OSpaceTypesLoaded); } return(true); } } } // Check if its loaded in the cache - if the call is for loading referenced assemblies, make sure that all referenced // assemblies are also loaded KnownAssemblyEntry entry; if (_knownAssemblies.TryGetKnownAssembly(assembly, _loaderCookie, edmItemCollection, out entry)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false) { // don't say we loaded anything, unless we actually did before return(entry.CacheEntry.TypesInAssembly.Count != 0); } else if (entry.ReferencedAssembliesAreLoaded) { // this assembly was part of a all hands reference search return(true); } } lock (LoadAssemblyLock) { // Check after acquiring the lock, since the known assemblies might have got modified // Check if the assembly is already loaded. The reason we need to check if the assembly is already loaded, is that if (_knownAssemblies.TryGetKnownAssembly(assembly, _loaderCookie, edmItemCollection, out entry)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false || entry.ReferencedAssembliesAreLoaded) { return(true); } } Dictionary <string, EdmType> typesInLoading; List <EdmItemError> errors; var knownAssemblies = new KnownAssembliesSet(_knownAssemblies); // Load the assembly from the cache AssemblyCache.LoadAssembly( assembly, loadReferencedAssemblies, knownAssemblies, edmItemCollection, logLoadMessage, ref _loaderCookie, out typesInLoading, out errors); // Throw if we have encountered errors if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errors)); } // We can encounter new assemblies, but they may not have any time in them if (typesInLoading.Count != 0) { // No errors, so go ahead and add the types and make them readonly // The existence of the loading lock tells us whether we should be thread safe or not, if we need // to be thread safe. We don't need to actually use the lock because the caller should have done // it already. // Recheck the assemblies added, another list is created just to match up the collection type // taken in by AddRange() AddLoadedTypes(typesInLoading); } // Update the value of known assemblies _knownAssemblies = knownAssemblies; return(typesInLoading.Count != 0); } }