public void action_should_throw_exception_when_func_delegate_expression_is_not_a_method()
        {
            // arrange
            var controllerBuilder = new ODataControllerQueryOptionsConventionBuilder <StubController>();
            var builder           = new Mock <ODataActionQueryOptionsConventionBuilder <StubController> >(controllerBuilder).Object;

            // act
            Action action = () => builder.Action(c => c.Timeout);

            // assert
            action.Should().Throw <InvalidOperationException>().And
            .Message.Should().Be("The expression 'c => c.Timeout' must refer to a controller action method.");
        }
        public void action_should_map_method_from_func_delegate_expression()
        {
            // arrange
            var method            = typeof(StubController).GetMethod(nameof(StubController.Get));
            var controllerBuilder = new ODataControllerQueryOptionsConventionBuilder <StubController>();
            var builder           = new Mock <ODataActionQueryOptionsConventionBuilder <StubController> >(controllerBuilder);

            // act
            builder.Object.Action(c => c.Get());

            // assert
            builder.Verify(b => b.Action(method), Once());
        }
        public void action_should_throw_exception_when_method_does_not_exist()
        {
            // arrange
            var message           = "An action method with the name 'NoSuchMethod' could not be found. The method must be public, non-static, and not have the NonActionAttribute applied.";
            var controllerBuilder = new ODataControllerQueryOptionsConventionBuilder(typeof(StubController));
            var builder           = new Mock <ODataActionQueryOptionsConventionBuilder>(controllerBuilder)
            {
                CallBase = true
            };

            // act
            Action actionConvention = () => builder.Object.Action("NoSuchMethod");

            // assert
            actionConvention.Should().Throw <MissingMethodException>().And.Message.Should().Be(message);
        }
        public void action_should_map_method_from_name_and_argument_type()
        {
            // arrange
            const string methodName        = nameof(StubController.Post);
            var          controllerType    = typeof(StubController);
            var          method            = controllerType.GetMethods().Single(m => m.Name == methodName && m.GetParameters().Length == 1);
            var          controllerBuilder = new ODataControllerQueryOptionsConventionBuilder(controllerType);
            var          builder           = new Mock <ODataActionQueryOptionsConventionBuilder>(controllerBuilder)
            {
                CallBase = true
            };

            // act
            builder.Object.Action(methodName, typeof(int));

            // assert
            builder.Verify(b => b.Action(method), Once());
        }
        /// <summary>
        /// Gets or creates the convention builder for the specified controller.
        /// </summary>
        /// <param name="controllerType">The <see cref="Type">type</see> of controller to build conventions for.</param>
        /// <returns>A new or existing <see cref="ODataControllerQueryOptionsConventionBuilder"/>.</returns>
        public virtual ODataControllerQueryOptionsConventionBuilder Controller(Type controllerType)
        {
            if (controllerType == null)
            {
                throw new ArgumentNullException(nameof(controllerType));
            }

            var key = GetKey(controllerType);

            if (!ConventionBuilders.TryGetValue(key, out var builder))
            {
                var newBuilder = new ODataControllerQueryOptionsConventionBuilder(controllerType);
                ConventionBuilders[key] = newBuilder;
                return(newBuilder);
            }

            if (builder is ODataControllerQueryOptionsConventionBuilder typedBuilder)
            {
                return(typedBuilder);
            }

            throw new InvalidOperationException(SR.ConventionStyleMismatch.FormatDefault(key.Name));
        }
        /// <summary>
        /// Applies the defined OData query option conventions to the specified API description.
        /// </summary>
        /// <param name="apiDescriptions">The <see cref="IEnumerable{T}">sequence</see> of <see cref="ApiDescription">API descriptions</see>
        /// to apply configured conventions to.</param>
        /// <param name="queryOptionSettings">The <see cref="ODataQueryOptionSettings">settings</see> used to apply OData query option conventions.</param>
        public virtual void ApplyTo(IEnumerable <ApiDescription> apiDescriptions, ODataQueryOptionSettings queryOptionSettings)
        {
            if (apiDescriptions == null)
            {
                throw new ArgumentNullException(nameof(apiDescriptions));
            }

            var conventions = new Dictionary <TypeInfo, IODataQueryOptionsConvention>();

            foreach (var description in apiDescriptions)
            {
                var controller = GetController(description);

                if (!conventions.TryGetValue(controller, out var convention))
                {
                    if (!controller.IsODataController() && !IsODataLike(description))
                    {
                        continue;
                    }

                    if (!ConventionBuilders.TryGetValue(controller, out var builder))
                    {
                        builder = new ODataControllerQueryOptionsConventionBuilder(controller);
                    }

                    convention = builder.Build(queryOptionSettings);
                    conventions.Add(controller, convention);
                }

                convention.ApplyTo(description);

                for (var i = 0; i < Conventions.Count; i++)
                {
                    Conventions[i].ApplyTo(description);
                }
            }
        }
        /// <summary>
        /// Gets or creates the convention builder for the specified controller.
        /// </summary>
        /// <typeparam name="TController">The <see cref="Type">type</see> of controller to build conventions for.</typeparam>
        /// <returns>A new or existing <see cref="ODataControllerQueryOptionsConventionBuilder{T}"/>.</returns>
        public virtual ODataControllerQueryOptionsConventionBuilder <TController> Controller <TController>()
            where TController : notnull
#if WEBAPI
#pragma warning disable SA1001 // Commas should be spaced correctly
        , IHttpController
#pragma warning restore SA1001 // Commas should be spaced correctly
#endif
        {
            var key = GetKey(typeof(TController));

            if (!ConventionBuilders.TryGetValue(key, out var builder))
            {
                var newBuilder = new ODataControllerQueryOptionsConventionBuilder <TController>();
                ConventionBuilders[key] = newBuilder;
                return(newBuilder);
            }

            if (builder is ODataControllerQueryOptionsConventionBuilder <TController> typedBuilder)
            {
                return(typedBuilder);
            }

            throw new InvalidOperationException(SR.ConventionStyleMismatch.FormatDefault(key.Name));
        }
Beispiel #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ODataActionQueryOptionsConventionBuilderCollection{T}"/> class.
 /// </summary>
 /// <param name="controllerBuilder">The associated <see cref="ODataControllerQueryOptionsConventionBuilder{T}">controller convention builder</see>.</param>
 public ODataActionQueryOptionsConventionBuilderCollection(ODataControllerQueryOptionsConventionBuilder <T> controllerBuilder) =>
 this.controllerBuilder = controllerBuilder;
 /// <summary>
 /// Initializes a new instance of the <see cref="ODataActionQueryOptionsConventionBuilder{T}"/> class.
 /// </summary>
 /// <param name="controllerBuilder">The <see cref="ODataActionQueryOptionsConventionBuilder{T}">controller builder</see>
 /// the action builder belongs to.</param>
 public ODataActionQueryOptionsConventionBuilder(ODataControllerQueryOptionsConventionBuilder <T> controllerBuilder) =>
 /// <summary>
 /// Initializes a new instance of the <see cref="ODataActionQueryOptionsConventionBuilder{T}"/> class.
 /// </summary>
 /// <param name="controllerBuilder">The <see cref="ODataActionQueryOptionsConventionBuilder{T}">controller builder</see>
 /// the action builder belongs to.</param>
 public ODataActionQueryOptionsConventionBuilder(ODataControllerQueryOptionsConventionBuilder <T> controllerBuilder)
 {
     Arg.NotNull(controllerBuilder, nameof(controllerBuilder));
     ControllerBuilder = controllerBuilder;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ODataActionQueryOptionsConventionBuilderCollection"/> class.
 /// </summary>
 /// <param name="controllerBuilder">The associated <see cref="ODataControllerQueryOptionsConventionBuilder">controller convention builder</see>.</param>
 public ODataActionQueryOptionsConventionBuilderCollection(ODataControllerQueryOptionsConventionBuilder controllerBuilder)
 {
     Arg.NotNull(controllerBuilder, nameof(controllerBuilder));
     this.controllerBuilder = controllerBuilder;
 }