示例#1
0
        public static IReadOnlyDictionary<string, object> CreatePropertyDictionary(
            this Delta entity, IEdmStructuredType edmType, ApiBase api, bool isCreation)
        {
            var propertiesAttributes = RetrievePropertiesAttributes(edmType, api);

            Dictionary<string, object> propertyValues = new Dictionary<string, object>();
            foreach (string propertyName in entity.GetChangedPropertyNames())
            {
                PropertyAttributes attributes;
                if (propertiesAttributes != null && propertiesAttributes.TryGetValue(propertyName, out attributes))
                {
                    if ((isCreation && (attributes & PropertyAttributes.IgnoreForCreation) != PropertyAttributes.None)
                      || (!isCreation && (attributes & PropertyAttributes.IgnoreForUpdate) != PropertyAttributes.None))
                    {
                        // Will not get the properties for update or creation
                        continue;
                    }
                }

                object value;
                if (entity.TryGetPropertyValue(propertyName, out value))
                {
                    var complexObj = value as EdmComplexObject;
                    if (complexObj != null)
                    {
                        value = CreatePropertyDictionary(complexObj, complexObj.ActualEdmType, api, isCreation);
                    }

                    propertyValues.Add(propertyName, value);
                }
            }

            return propertyValues;
        }
        /// <summary>
        /// Sets the API instance to the <see cref="HttpRequestMessage"/>.
        /// </summary>
        /// <param name="request">The HTTP request.</param>
        /// <param name="apiInstance">The API instance.</param>
        internal static void SetApiInstance(this HttpRequestMessage request, ApiBase apiInstance)
        {
            Ensure.NotNull(request, "request");
            Ensure.NotNull(apiInstance, "apiInstance");

            request.Properties[ApiInstanceKey] = apiInstance;
        }
示例#3
0
        public RestierQueryBuilder(ApiBase api, ODataPath path)
        {
            Ensure.NotNull(api, "api");
            Ensure.NotNull(path, "path");
            this.api = api;
            this.path = path;

            this.handlers[ODataSegmentKinds.EntitySet] = this.HandleEntitySetPathSegment;
            this.handlers[ODataSegmentKinds.Singleton] = this.HandleSingletonPathSegment;
            this.handlers[ODataSegmentKinds.UnboundFunction] = this.HandleUnboundFunctionPathSegment;
            this.handlers[ODataSegmentKinds.Count] = this.HandleCountPathSegment;
            this.handlers[ODataSegmentKinds.Value] = this.HandleValuePathSegment;
            this.handlers[ODataSegmentKinds.Key] = this.HandleKeyValuePathSegment;
            this.handlers[ODataSegmentKinds.Navigation] = this.HandleNavigationPathSegment;
            this.handlers[ODataSegmentKinds.Property] = this.HandlePropertyAccessPathSegment;
        }
示例#4
0
        /// <summary>
        /// Asynchronously gets an API model using an API context.
        /// </summary>
        /// <param name="api">
        /// An API.
        /// </param>
        /// <param name="cancellationToken">
        /// An optional cancellation token.
        /// </param>
        /// <returns>
        /// A task that represents the asynchronous
        /// operation whose result is the API model.
        /// </returns>
        public static async Task <IEdmModel> GetModelAsync(
            this ApiBase api,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Ensure.NotNull(api, "api");

            var config = api.Configuration;

            if (config.Model != null)
            {
                return(config.Model);
            }

            var builder = api.GetApiService <IModelBuilder>();

            if (builder == null)
            {
                throw new InvalidOperationException(Resources.ModelBuilderNotRegistered);
            }

            Task <IEdmModel> running;
            var source = config.CompeteModelGeneration(out running);

            if (source == null)
            {
                return(await running);
            }

            try
            {
                var buildContext = new ModelContext(api.ServiceProvider);
                var model        = await builder.GetModelAsync(buildContext, cancellationToken);

                source.SetResult(model);
                return(model);
            }
            catch (AggregateException e)
            {
                source.SetException(e.InnerExceptions);
                throw;
            }
            catch (Exception e)
            {
                source.SetException(e);
                throw;
            }
        }
示例#5
0
        /// <summary>
        /// Gets a queryable source of data using an API context.
        /// </summary>
        /// <typeparam name="TElement">
        /// The type of the elements in the queryable source.
        /// </typeparam>
        /// <param name="api">
        /// An API.
        /// </param>
        /// <param name="name">
        /// The name of an entity set, singleton or composable function import.
        /// </param>
        /// <param name="arguments">
        /// If <paramref name="name"/> is a composable function import,
        /// the arguments to be passed to the composable function import.
        /// </param>
        /// <returns>
        /// A queryable source.
        /// </returns>
        /// <remarks>
        /// <para>
        /// If the name identifies a singleton or a composable function import
        /// whose result is a singleton, the resulting queryable source will
        /// be configured such that it represents exactly zero or one result.
        /// </para>
        /// <para>
        /// Note that the resulting queryable source cannot be synchronously
        /// enumerated, as the API engine only operates asynchronously.
        /// </para>
        /// </remarks>
        public static IQueryable <TElement> GetQueryableSource <TElement>(
            this ApiBase api,
            string name,
            params object[] arguments)
        {
            Ensure.NotNull(api, "api");
            Ensure.NotNull(name, "name");

            var elementType = api.EnsureElementType(null, name);

            if (typeof(TElement) != elementType)
            {
                throw new ArgumentException(Resources.ElementTypeNotMatch);
            }

            return(SourceCore <TElement>(null, name, arguments));
        }
        public RestierQueryBuilder(ApiBase api, ODataPath path)
        {
            Ensure.NotNull(api, "api");
            Ensure.NotNull(path, "path");
            this.api = api;
            this.path = path;

            this.handlers[typeof(EntitySetSegment)] = this.HandleEntitySetPathSegment;
            this.handlers[typeof(SingletonSegment)] = this.HandleSingletonPathSegment;
            this.handlers[typeof(OperationSegment)] = this.EmptyHandler;
            this.handlers[typeof(OperationImportSegment)] = this.EmptyHandler;
            this.handlers[typeof(CountSegment)] = this.HandleCountPathSegment;
            this.handlers[typeof(ValueSegment)] = this.HandleValuePathSegment;
            this.handlers[typeof(KeySegment)] = this.HandleKeyValuePathSegment;
            this.handlers[typeof(NavigationPropertySegment)] = this.HandleNavigationPathSegment;
            this.handlers[typeof(PropertySegment)] = this.HandlePropertyAccessPathSegment;
            this.handlers[typeof(TypeSegment)] = this.HandleEntityTypeSegment;

            // Complex cast is not supported by EF, and is not supported here
            // this.handlers[ODataSegmentKinds.ComplexCast] = null;
        }
示例#7
0
 /// <summary>
 /// Removes a property.
 /// </summary>
 /// <param name="api">An API. </param>
 /// <param name="name">The name of a property.</param>
 public static void RemoveProperty(this ApiBase api, string name) => api.GetPropertyBag().RemoveProperty(name);
示例#8
0
 /// <summary>
 /// Sets a property.
 /// </summary>
 /// <param name="api">An API.</param>
 /// <param name="name">The name of a property.</param>
 /// <param name="value">A value for the property.</param>
 public static void SetProperty(this ApiBase api, string name, object value) => api.GetPropertyBag().SetProperty(name, value);
示例#9
0
 /// <summary>
 /// Gets a property.
 /// </summary>
 /// <param name="api">An API.</param>
 /// <param name="name">The name of a property.</param>
 /// <returns>
 /// The value of the property.
 /// </returns>
 public static object GetProperty(this ApiBase api, string name) => api.GetPropertyBag().GetProperty(name);
示例#10
0
        public static Type GetClrType(this IEdmType edmType, ApiBase api)
        {
            IEdmModel edmModel = api.GetModelAsync().Result;

            ClrTypeAnnotation annotation = edmModel.GetAnnotationValue<ClrTypeAnnotation>(edmType);
            if (annotation != null)
            {
                return annotation.ClrType;
            }

            throw new NotSupportedException(string.Format(
                CultureInfo.InvariantCulture,
                Resources.ElementTypeNotFound,
                edmType.FullTypeName()));
        }
示例#11
0
 /// <summary>
 /// Indicates if this object has a property.
 /// </summary>
 /// <param name="api">An API.</param>
 /// <param name="name"> The name of a property.</param>
 /// <returns>
 /// <c>true</c> if this object has the property; otherwise, <c>false</c>.
 /// </returns>
 public static bool HasProperty(this ApiBase api, string name) => api.GetPropertyBag().HasProperty(name);
示例#12
0
 /// <summary>
 /// Gets a service instance.
 /// </summary>
 /// <param name="api">
 /// An API.
 /// </param>
 /// <typeparam name="T">The service type.</typeparam>
 /// <returns>The service instance.</returns>
 public static T GetApiService <T>(this ApiBase api) where T : class
 {
     Ensure.NotNull(api, "api");
     return(api.ServiceProvider.GetService <T>());
 }
示例#13
0
 /// <summary>
 /// Gets a property.
 /// </summary>
 /// <param name="api">
 /// An API.
 /// </param>
 /// <param name="name">
 /// The name of a property.
 /// </param>
 /// <returns>
 /// The value of the property.
 /// </returns>
 public static object GetProperty(this ApiBase api, string name)
 {
     return(api.GetPropertyBag().GetProperty(name));
 }
示例#14
0
 /// <summary>
 /// Gets a property.
 /// </summary>
 /// <typeparam name="T">
 /// The type of the property.
 /// </typeparam>
 /// <param name="api">
 /// An API.
 /// </param>
 /// <param name="name">
 /// The name of a property.
 /// </param>
 /// <returns>
 /// The value of the property.
 /// </returns>
 public static T GetProperty <T>(this ApiBase api, string name)
 {
     return(api.GetPropertyBag().GetProperty <T>(name));
 }
示例#15
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="api"></param>
 /// <returns></returns>
 private static PropertyBag GetPropertyBag(this ApiBase api)
 {
     Ensure.NotNull(api, nameof(api));
     return(api.GetApiService <PropertyBag>());
 }
示例#16
0
 /// <summary>
 /// Gets all registered service instances.
 /// </summary>
 /// <param name="api">
 /// An API.
 /// </param>
 /// <typeparam name="T">The service type.</typeparam>
 /// <returns>The ordered collection of service instances.</returns>
 public static IEnumerable <T> GetApiServices <T>(this ApiBase api) where T : class
 {
     Ensure.NotNull(api, nameof(api));
     return(api.ServiceProvider.GetServices <T>());
 }
示例#17
0
 /// <summary>
 /// Indicates if this object has a property.
 /// </summary>
 /// <param name="api">
 /// An API.
 /// </param>
 /// <param name="name">
 /// The name of a property.
 /// </param>
 /// <returns>
 /// <c>true</c> if this object has the
 /// property; otherwise, <c>false</c>.
 /// </returns>
 public static bool HasProperty(this ApiBase api, string name)
 {
     return(api.GetPropertyBag().HasProperty(name));
 }
示例#18
0
 /// <summary>
 /// Gets a property.
 /// </summary>
 /// <typeparam name="T">The type of the property.
 /// </typeparam>
 /// <param name="api">An API.</param>
 /// <param name="name">The name of a property. </param>
 /// <returns>
 /// The value of the property.
 /// </returns>
 public static T GetProperty <T>(this ApiBase api, string name) => api.GetPropertyBag().GetProperty <T>(name);
示例#19
0
        public static IDictionary<string, PropertyAttributes> RetrievePropertiesAttributes(
            IEdmStructuredType edmType, ApiBase api)
        {
            IDictionary<string, PropertyAttributes> propertiesAttributes;
            if (typePropertiesAttributes.TryGetValue(edmType, out propertiesAttributes))
            {
                return propertiesAttributes;
            }

            var model = api.Context.GetModelAsync().Result;
            foreach (var property in edmType.DeclaredProperties)
            {
                var annotations = model.FindVocabularyAnnotations(property);
                var attributes = PropertyAttributes.None;
                foreach (var annotation in annotations)
                {
                    var valueAnnotation = annotation as EdmVocabularyAnnotation;
                    if (valueAnnotation == null)
                    {
                        continue;
                    }

                    if (valueAnnotation.Term.IsSameTerm(CoreVocabularyModel.ImmutableTerm))
                    {
                        var value = valueAnnotation.Value as EdmBooleanConstant;
                        if (value != null && value.Value)
                        {
                            attributes |= PropertyAttributes.IgnoreForUpdate;
                        }
                    }

                    if (valueAnnotation.Term.IsSameTerm(CoreVocabularyModel.ComputedTerm))
                    {
                        var value = valueAnnotation.Value as EdmBooleanConstant;
                        if (value != null && value.Value)
                        {
                            attributes |= PropertyAttributes.IgnoreForUpdate;
                            attributes |= PropertyAttributes.IgnoreForCreation;
                        }
                    }

                    // TODO add permission annotation check
                    // CoreVocabularyModel has no permission yet, will add with #480
                }

                // Add property attributes to the dictionary
                if (attributes != PropertyAttributes.None)
                {
                    if (propertiesAttributes == null)
                    {
                        propertiesAttributes = new Dictionary<string, PropertyAttributes>();
                        typePropertiesAttributes[edmType] = propertiesAttributes;
                    }

                    propertiesAttributes.Add(property.Name, attributes);
                }
            }

            return propertiesAttributes;
        }