Ejemplo n.º 1
0
        /// <summary>
        /// Get the client type annotation for the given name.
        /// </summary>
        /// <param name="edmTypeName">Name of the type.</param>
        /// <returns>An instance of ClientTypeAnnotation for the type with the given name.</returns>
        internal ClientTypeAnnotation GetClientTypeAnnotation(string edmTypeName)
        {
            Debug.Assert(WebUtil.GetCollectionItemWireTypeName(edmTypeName) == null, "This method must not be called for collections");
            IEdmType result = this.clrToEdmTypeCache.Values.First(e => e.EdmType.FullName() == edmTypeName).EdmType;

            Debug.Assert(result != null, "result != null");
            return(this.GetClientTypeAnnotation(result));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Resolves the client type that should be used for materialization.
        /// </summary>
        /// <param name="expectedType">Expected client clr type based on the API called.</param>
        /// <param name="readerTypeName">
        /// The name surfaced by the ODataLib reader.
        /// If we have a server model, this will be a server type name that needs to be resolved.
        /// If not, then this will already be a client type name.</param>
        /// <returns>The resolved annotation for the client type to materialize into.</returns>
        internal ClientTypeAnnotation ResolveTypeForMaterialization(Type expectedType, string readerTypeName)
        {
            // If its a collection, get the collection item name
            string collectionItemTypeName = WebUtil.GetCollectionItemWireTypeName(readerTypeName);

            if (collectionItemTypeName == null)
            {
                // Resolve the primitive type first
                PrimitiveType primitiveType;
                if (PrimitiveType.TryGetPrimitiveType(readerTypeName, out primitiveType))
                {
                    return(this.clientEdmModel.GetClientTypeAnnotation(primitiveType.ClrType));
                }

                ClientTypeAnnotation resultType;
                if (this.edmTypeNameMap.TryGetValue(readerTypeName, out resultType))
                {
                    return(resultType);
                }

                if (this.serviceModel != null)
                {
                    var resolvedType = this.ResolveTypeFromName(readerTypeName, expectedType);
                    return(this.clientEdmModel.GetClientTypeAnnotation(resolvedType));
                }

                // If there was no type name specified in the payload, then the type resolver won't be invoked
                // and hence that edm type name might not be in the resolver cache. Hence look that up in the
                // ClientEdmModel cache. This lookup is more expensive and is unique across the app domain for the
                // given version.
                return(this.clientEdmModel.GetClientTypeAnnotation(readerTypeName));
            }

            Type collectionImplementationType = ClientTypeUtil.GetImplementationType(expectedType, typeof(ICollection <>));
            Type collectionElementType        = collectionImplementationType.GetGenericArguments()[0];

            // In case of collection, the expectedType might be collection of nullable types (for e.g. ICollection<int?>).
            // There is no way to know the nullability from the wireTypeName (For e.g. Collection(Edm.Int32)).
            // Hence in case of collections of primitives, we need to look at the element type of the expected type
            // and use that to create the instance otherwise we will not be able to assign the created ICollection<>
            // instance to the property on the user's entity (ICollection<int> cannot be assigned to ICollection<int?>).
            // There is also no need to invoke the resolver for primitives, so we just use the element type.
            if (!PrimitiveType.IsKnownType(collectionElementType))
            {
                collectionElementType = this.ResolveTypeForMaterialization(collectionElementType, collectionItemTypeName).ElementType;
            }

            Type clrCollectionType = WebUtil.GetBackingTypeForCollectionProperty(expectedType);

            return(this.clientEdmModel.GetClientTypeAnnotation(clrCollectionType));
        }