internal static ObjectItemAssemblyLoader CreateLoader(Assembly assembly, ObjectItemLoadingSessionData sessionData) { ImmutableAssemblyCacheEntry cacheEntry; // KnownAssembly -> NoOp // Inside the LockedAssemblyCache means it is an attribute based assembly -> Cachedassembly // Inside the OcCache on EdmItemCollection -> cachedassembly // If none of above, setup the LoaderFactory based on the current assembly and EdmItemCollection if (sessionData.KnownAssemblies.Contains(assembly, sessionData.ObjectItemAssemblyLoaderFactory, sessionData.EdmItemCollection)) { return new ObjectItemNoOpAssemblyLoader(assembly, sessionData); } else if (sessionData.LockedAssemblyCache.TryGetValue(assembly, out cacheEntry)) { if (sessionData.ObjectItemAssemblyLoaderFactory == null) { if (cacheEntry.TypesInAssembly.Count != 0) { // we are loading based on attributes now sessionData.ObjectItemAssemblyLoaderFactory = ObjectItemAttributeAssemblyLoader.Create; } // if types in assembly are 0, don't commit to any loader yet } else if (sessionData.ObjectItemAssemblyLoaderFactory != ObjectItemAttributeAssemblyLoader.Create) { // we were loading in convention mode, and ran into an assembly that can't be loaded by convention // we know this because all cached assemblies are attribute based at the moment. sessionData.EdmItemErrors.Add( new EdmItemError(Strings.Validator_OSpace_Convention_AttributeAssemblyReferenced(assembly.FullName))); } return new ObjectItemCachedAssemblyLoader(assembly, cacheEntry, sessionData); } else if (sessionData.EdmItemCollection != null && sessionData.EdmItemCollection.ConventionalOcCache.TryGetConventionalOcCacheFromAssemblyCache( assembly, out cacheEntry)) { sessionData.ObjectItemAssemblyLoaderFactory = ObjectItemConventionAssemblyLoader.Create; return new ObjectItemCachedAssemblyLoader(assembly, cacheEntry, sessionData); } else if (sessionData.ObjectItemAssemblyLoaderFactory == null) { if (ObjectItemAttributeAssemblyLoader.IsSchemaAttributePresent(assembly)) { sessionData.ObjectItemAssemblyLoaderFactory = ObjectItemAttributeAssemblyLoader.Create; } else if (ObjectItemConventionAssemblyLoader.SessionContainsConventionParameters(sessionData)) { sessionData.ObjectItemAssemblyLoaderFactory = ObjectItemConventionAssemblyLoader.Create; } } if (sessionData.ObjectItemAssemblyLoaderFactory != null) { return sessionData.ObjectItemAssemblyLoaderFactory(assembly, sessionData); } return new ObjectItemNoOpAssemblyLoader(assembly, sessionData); }
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; } }
protected static void LoadAssemblies(IEnumerable<Assembly> assemblies, ObjectItemLoadingSessionData sessionData) { foreach (Assembly assembly in assemblies) { ObjectItemAssemblyLoader loader = ObjectItemAssemblyLoader.CreateLoader(assembly, sessionData); loader.Load(); } }
internal static ObjectItemAssemblyLoader CreateLoader(Assembly assembly, ObjectItemLoadingSessionData sessionData) { ImmutableAssemblyCacheEntry cacheEntry; // KnownAssembly -> NoOp // Inside the LockedAssemblyCache means it is an attribute based assembly -> Cachedassembly // Inside the OcCache on EdmItemCollection -> cachedassembly // If none of above, setup the LoaderFactory based on the current assembly and EdmItemCollection if (sessionData.KnownAssemblies.Contains(assembly, sessionData.ObjectItemAssemblyLoaderFactory, sessionData.EdmItemCollection)) { return new ObjectItemNoOpAssemblyLoader(assembly, sessionData); } else if (sessionData.LockedAssemblyCache.TryGetValue(assembly, out cacheEntry)) { if (sessionData.ObjectItemAssemblyLoaderFactory == null) { if (cacheEntry.TypesInAssembly.Count != 0) { // we are loading based on attributes now sessionData.ObjectItemAssemblyLoaderFactory = ObjectItemAttributeAssemblyLoader.Create; } // if types in assembly are 0, don't commit to any loader yet } else if (sessionData.ObjectItemAssemblyLoaderFactory != ObjectItemAttributeAssemblyLoader.Create) { // we were loading in convention mode, and ran into an assembly that can't be loaded by convention // we know this because all cached assemblies are attribute based at the moment. sessionData.EdmItemErrors.Add(new EdmItemError(Strings.Validator_OSpace_Convention_AttributeAssemblyReferenced(assembly.FullName), null)); } return new ObjectItemCachedAssemblyLoader(assembly, cacheEntry, sessionData); } else if (sessionData.EdmItemCollection != null && sessionData.EdmItemCollection.ConventionalOcCache.TryGetConventionalOcCacheFromAssemblyCache( assembly, out cacheEntry)) { sessionData.ObjectItemAssemblyLoaderFactory = ObjectItemConventionAssemblyLoader.Create; return new ObjectItemCachedAssemblyLoader(assembly, cacheEntry, sessionData); } else if (sessionData.ObjectItemAssemblyLoaderFactory == null) { if (ObjectItemAttributeAssemblyLoader.IsSchemaAttributePresent(assembly)) { sessionData.ObjectItemAssemblyLoaderFactory = ObjectItemAttributeAssemblyLoader.Create; } else if (ObjectItemConventionAssemblyLoader.SessionContainsConventionParameters(sessionData)) { sessionData.ObjectItemAssemblyLoaderFactory = ObjectItemConventionAssemblyLoader.Create; } } if (sessionData.ObjectItemAssemblyLoaderFactory != null) { return sessionData.ObjectItemAssemblyLoaderFactory(assembly, sessionData); } return new ObjectItemNoOpAssemblyLoader(assembly, sessionData); }
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 (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; } }
internal static ObjectItemAssemblyLoader Create(Assembly assembly, ObjectItemLoadingSessionData sessionData) { if (ObjectItemAttributeAssemblyLoader.IsSchemaAttributePresent(assembly)) { return(new ObjectItemAttributeAssemblyLoader(assembly, sessionData)); } else { return(new ObjectItemNoOpAssemblyLoader(assembly, sessionData)); } }
internal static ObjectItemAssemblyLoader Create(Assembly assembly, ObjectItemLoadingSessionData sessionData) { if (!ObjectItemAttributeAssemblyLoader.IsSchemaAttributePresent(assembly)) { return(new ObjectItemConventionAssemblyLoader(assembly, sessionData)); } else { // we were loading in convention mode, and ran into an assembly that can't be loaded by convention sessionData.EdmItemErrors.Add(new EdmItemError(Strings.Validator_OSpace_Convention_AttributeAssemblyReferenced(assembly.FullName), null)); return(new ObjectItemNoOpAssemblyLoader(assembly, sessionData)); } }
internal ObjectItemAttributeAssemblyLoader(Assembly assembly, ObjectItemLoadingSessionData sessionData) : base(assembly, new MutableAssemblyCacheEntry(), sessionData) { Debug.Assert(Create == sessionData.ObjectItemAssemblyLoaderFactory, "Why is there a different factory creating this class"); }
internal ObjectItemConventionAssemblyLoader(Assembly assembly, ObjectItemLoadingSessionData sessionData) : base(assembly, new MutableAssemblyCacheEntry(), sessionData) { Debug.Assert(Create == sessionData.ObjectItemAssemblyLoaderFactory, "Why is there a different factory creating this class"); SessionData.RegisterForLevel1PostSessionProcessing(this); }
protected ObjectItemAssemblyLoader(Assembly assembly, AssemblyCacheEntry cacheEntry, ObjectItemLoadingSessionData sessionData) { _assembly = assembly; _cacheEntry = cacheEntry; _sessionData = sessionData; }
internal static bool SessionContainsConventionParameters(ObjectItemLoadingSessionData sessionData) { return(sessionData.EdmItemCollection != null); }
internal ObjectItemNoOpAssemblyLoader(Assembly assembly, ObjectItemLoadingSessionData sessionData) : base(assembly, new MutableAssemblyCacheEntry(), sessionData) { }
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 // recursive call LoadAssembly(referencedAssembly, loadReferencedAssemblies, loadingData); } } }
internal static ObjectItemAssemblyLoader Create(Assembly assembly, ObjectItemLoadingSessionData sessionData) { if (ObjectItemAttributeAssemblyLoader.IsSchemaAttributePresent(assembly)) { return new ObjectItemAttributeAssemblyLoader(assembly, sessionData); } else { return new ObjectItemNoOpAssemblyLoader(assembly, sessionData); } }
internal ObjectItemAttributeAssemblyLoader(Assembly assembly, ObjectItemLoadingSessionData sessionData) :base(assembly, new MutableAssemblyCacheEntry(), sessionData) { Debug.Assert(Create == sessionData.ObjectItemAssemblyLoaderFactory, "Why is there a different factory creating this class"); }
internal ObjectItemCachedAssemblyLoader(Assembly assembly, ImmutableAssemblyCacheEntry cacheEntry, ObjectItemLoadingSessionData sessionData) : base(assembly, cacheEntry, sessionData) { }
internal static bool SessionContainsConventionParameters(ObjectItemLoadingSessionData sessionData) { return sessionData.EdmItemCollection != null; }
internal static ObjectItemAssemblyLoader Create(Assembly assembly, ObjectItemLoadingSessionData sessionData) { if (!ObjectItemAttributeAssemblyLoader.IsSchemaAttributePresent(assembly)) { return new ObjectItemConventionAssemblyLoader(assembly, sessionData); } else { // we were loading in convention mode, and ran into an assembly that can't be loaded by convention sessionData.EdmItemErrors.Add(new EdmItemError(Strings.Validator_OSpace_Convention_AttributeAssemblyReferenced(assembly.FullName), null)); return new ObjectItemNoOpAssemblyLoader(assembly, sessionData); } }