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; } }
public void CsdlAnnotations() { DataServiceConfiguration config; DataServiceOperationContext operationContext; DataServiceProviderWrapper provider = CreateProvider(out config, out operationContext); IEnumerable <EdmError> errors; config.AnnotationsBuilder = (model) => { XmlReader[] xmlReaders; bool parsed; IEdmModel vocabularyModel; xmlReaders = new XmlReader[] { XmlReader.Create(new StringReader(vocabulary)) }; parsed = SchemaReader.TryParse(xmlReaders, out vocabularyModel, out errors); Assert.IsTrue(parsed); IEdmModel annotationsModel1; xmlReaders = new XmlReader[] { XmlReader.Create(new StringReader(annotations1)) }; parsed = SchemaReader.TryParse(xmlReaders, new IEdmModel[] { model, vocabularyModel }, out annotationsModel1, out errors); Assert.IsTrue(parsed); IEdmModel annotationsModel2; xmlReaders = new XmlReader[] { XmlReader.Create(new StringReader(annotations2)) }; parsed = SchemaReader.TryParse(xmlReaders, new IEdmModel[] { model, vocabularyModel }, out annotationsModel2, out errors); Assert.IsTrue(parsed); // Annotations are intentionally duplicated to test duplicate filtering return(new IEdmModel[] { annotationsModel1, annotationsModel2, annotationsModel2, annotationsModel1 }); }; IEdmModel annotatedModel = MetadataSerializer.PrepareModelForSerialization(provider, config); Assert.AreEqual(v4, provider.ResponseMetadataVersion); // TODO: Stop accounting for invalid names EdmValidator.Validate(annotatedModel, out errors); Assert.AreEqual(validAnnotationsCount, errors.Count()); Assert.IsTrue(errors.All(e => e.ErrorCode == EdmErrorCode.BadUnresolvedTerm)); Version edmxVersion = v4; MetadataSerializer.ValidateModel(annotatedModel, edmxVersion); IEdmEntityContainer customersContainer; IEdmEntitySet customersSet; IEdmEntityType customerType; VerifyEntitySetsAndTypes(annotatedModel, out customersContainer, out customersSet, out customerType); Assert.AreEqual(validAnnotationsCount, annotatedModel.VocabularyAnnotations.Count()); IEdmVocabularyAnnotation[] customerAnnotations = annotatedModel.FindDeclaredVocabularyAnnotations(customerType).ToArray(); Assert.AreEqual(2, customerAnnotations.Count()); var ratingPrimary = customerAnnotations[0]; Assert.AreEqual(customerType, ratingPrimary.Target); Assert.AreEqual("Primary", ratingPrimary.Qualifier); Assert.AreEqual("Rating", ratingPrimary.Term.Name); Assert.AreEqual(1, ((IEdmIntegerConstantExpression)ratingPrimary.Value).Value); var ratingSecondary = customerAnnotations[1]; Assert.AreEqual(customerType, ratingSecondary.Target); Assert.AreEqual("Secondary", ratingSecondary.Qualifier); Assert.AreEqual("Rating", ratingSecondary.Term.Name); Assert.AreEqual(2, ((IEdmIntegerConstantExpression)ratingSecondary.Value).Value); IEdmVocabularyAnnotation canEdit; canEdit = annotatedModel.FindDeclaredVocabularyAnnotations(customersContainer).Single(); Assert.AreEqual(customersContainer, canEdit.Target); Assert.AreEqual("CanEdit", canEdit.Term.Name); Assert.AreEqual(true, ((IEdmBooleanConstantExpression)canEdit.Value).Value); canEdit = annotatedModel.FindDeclaredVocabularyAnnotations(customersSet).Single(); Assert.AreEqual(customersSet, canEdit.Target); Assert.AreEqual("CanEdit", canEdit.Term.Name); Assert.AreEqual(true, ((IEdmBooleanConstantExpression)canEdit.Value).Value); IEdmProperty firstNameProperty = customerType.FindProperty("FirstName"); canEdit = annotatedModel.FindDeclaredVocabularyAnnotations(firstNameProperty).Single(); Assert.AreEqual(firstNameProperty, canEdit.Target); Assert.AreEqual("CanEdit", canEdit.Term.Name); Assert.AreEqual(true, ((IEdmBooleanConstantExpression)canEdit.Value).Value); }