/// <summary> /// Gets vocabulary annotation that binds to a term and a qualifier from the metadata annotation dictionary in current data service context for a specified type. /// </summary> /// <param name="context">The data service context.</param> /// <param name="type">The specified annotated type.</param> /// <param name="term">The term name.</param> /// <param name="qualifier">The qualifier name.</param> /// <returns>The vocabulary annotation that binds to a term and a qualifier for the specified annotated type.</returns> private static IEdmVocabularyAnnotation GetOrInsertCachedMetadataAnnotationForType(DataServiceContext context, Type type, string term, string qualifier) { var serviceModel = context.Format.ServiceModel; if (serviceModel == null) { return(null); } IEdmVocabularyAnnotation edmValueAnnotation = GetCachedMetadataAnnotation(context, type, term, qualifier); if (edmValueAnnotation != null) { return(edmValueAnnotation); } IEdmVocabularyAnnotatable edmVocabularyAnnotatable = null; if (type.IsSubclassOf(typeof(DataServiceContext))) { edmVocabularyAnnotatable = serviceModel.EntityContainer; } else { var serversideName = context.ResolveName == null ? type.FullName : context.ResolveName(type); if (!string.IsNullOrWhiteSpace(serversideName)) { edmVocabularyAnnotatable = serviceModel.FindDeclaredType(serversideName); if (edmVocabularyAnnotatable == null) { return(null); } } } // Gets the annotations which exactly match the qualifier and target. var edmValueAnnotations = serviceModel.FindVocabularyAnnotations <IEdmVocabularyAnnotation>(edmVocabularyAnnotatable, term, qualifier) .Where(a => a.Qualifier == qualifier && a.Target == edmVocabularyAnnotatable); if (!edmValueAnnotations.Any()) { edmValueAnnotation = GetOrInsertCachedMetadataAnnotationForType(context, type.GetBaseType(), term, qualifier); } else if (edmValueAnnotations.Count() == 1) { edmValueAnnotation = edmValueAnnotations.Single(); } InsertMetadataAnnotation(context, type, edmValueAnnotation); return(edmValueAnnotation); }
/// <summary> /// Gets vocabulary annotation that binds to a term and a qualifier from the metadata annotation dictionary in current data service context for a specified propertyInfo. /// </summary> /// <param name="context">The data service context.</param> /// <param name="propertyInfo">The specified annotated propertyInfo.</param> /// <param name="term">The term name.</param> /// <param name="qualifier">The qualifier name.</param> /// <returns>The vocabulary annotation that binds to a term and a qualifier for the specified annotated propertyInfo.</returns> private static IEdmVocabularyAnnotation GetOrInsertCachedMetadataAnnotationForPropertyInfo(DataServiceContext context, PropertyInfo propertyInfo, string term, string qualifier) { var serviceModel = context.Format.ServiceModel; if (serviceModel == null) { return(null); } IEdmVocabularyAnnotation edmValueAnnotation = GetCachedMetadataAnnotation(context, propertyInfo, term, qualifier); if (edmValueAnnotation != null) { return(edmValueAnnotation); } var severSidePropertyName = ClientTypeUtil.GetServerDefinedName(propertyInfo); if (string.IsNullOrEmpty(severSidePropertyName)) { return(null); } var declaringType = propertyInfo.DeclaringType; IEnumerable <IEdmVocabularyAnnotation> edmValueAnnotations = null; if (declaringType.IsSubclassOf(typeof(DataServiceContext))) { var entityContainer = serviceModel.EntityContainer; var edmEntityContainerElements = entityContainer.Elements.Where(e => e.Name == severSidePropertyName); if (edmEntityContainerElements != null && edmEntityContainerElements.Count() == 1) { edmValueAnnotations = serviceModel.FindVocabularyAnnotations <IEdmVocabularyAnnotation>( edmEntityContainerElements.Single(), term, qualifier).Where(a => a.Qualifier == qualifier); } } else { var serversideTypeName = context.ResolveName == null ? declaringType.FullName : context.ResolveName(declaringType); var edmType = serviceModel.FindDeclaredType(serversideTypeName); if (edmType != null) { var edmStructuredType = edmType as IEdmStructuredType; if (edmStructuredType != null) { var edmProperty = edmStructuredType.FindProperty(severSidePropertyName); if (edmProperty != null) { edmValueAnnotations = serviceModel.FindVocabularyAnnotations <IEdmVocabularyAnnotation>( edmProperty, term, qualifier).Where(a => a.Qualifier == qualifier); } } } } if (edmValueAnnotations != null && edmValueAnnotations.Count() == 1) { edmValueAnnotation = edmValueAnnotations.Single(); InsertMetadataAnnotation(context, propertyInfo, edmValueAnnotation); return(edmValueAnnotation); } return(null); }
/// <summary> /// Get Edm operation according to the MethodInfo from current data service context. /// </summary> /// <param name="context">The data service context.</param> /// <param name="methodInfo">The specified MethodInfo</param> /// <returns>The related <see cref="IEdmOperation"/> will be returned if it is found, or return null.</returns> internal static IEdmOperation GetEdmOperation(DataServiceContext context, MethodInfo methodInfo) { var serviceModel = context.Format.ServiceModel; if (serviceModel == null) { return(null); } var parameterTypes = methodInfo.GetParameters().Select(p => p.ParameterType).ToArray(); Type bindingType = null; IEnumerable <Type> clientParameters; if (methodInfo.IsDefined(typeof(ExtensionAttribute), false)) { bindingType = parameterTypes.First(); clientParameters = parameterTypes.Skip(1); } else { bindingType = methodInfo.DeclaringType; clientParameters = parameterTypes; } var declaringType = methodInfo.DeclaringType; string methodInfoNameSpacePrefix = declaringType.Namespace + "."; if (context.ResolveName != null) { string serverSideDeclaringTypeName = context.ResolveName(declaringType); if (serverSideDeclaringTypeName != null) { int index = serverSideDeclaringTypeName.LastIndexOf('.'); methodInfoNameSpacePrefix = index > 0 ? serverSideDeclaringTypeName.Substring(0, index + 1) : ""; } } var serverSideMethodName = ClientTypeUtil.GetServerDefinedName(methodInfo); var operations = serviceModel.FindOperations(methodInfoNameSpacePrefix + serverSideMethodName).Where(o => o.IsBound); while (bindingType != null) { foreach (var operation in operations) { Type bindingTypeFromTypeReference; if (TryGetClrTypeFromEdmTypeReference( context, operation.Parameters.First().Type, methodInfo.IsDefined(typeof(ExtensionAttribute), false), out bindingTypeFromTypeReference) && bindingTypeFromTypeReference == bindingType && clientParameters.SequenceEqual(GetNonBindingParameterTypeArray(context, operation.Parameters, true))) { return(operation); } } if (methodInfo.IsDefined(typeof(ExtensionAttribute), false) && bindingType.IsGenericType()) { var genericTypeDefinition = bindingType.GetGenericTypeDefinition(); var genericArguments = bindingType.GetGenericArguments().ToList(); if (genericArguments.Count == 1) { var genericArgumentBaseType = genericArguments[0].GetBaseType(); if (genericArgumentBaseType != null) { bindingType = genericTypeDefinition.MakeGenericType(genericArgumentBaseType); continue; } } } return(null); } return(null); }