public void Match_UsesODataDefaultRoutingConventions_IfControllerFound(string expectedControllerName,
                                                                               string entitySetName)
        {
            // Arrange
            const string routeName       = "api";
            var          request         = new HttpRequestMessage(HttpMethod.Get, "http://any/" + entitySetName);
            var          routeCollection = new HttpRouteCollection {
                { routeName, new HttpRoute() }
            };
            var config = new HttpConfiguration(routeCollection);

            request.SetConfiguration(config);
            var pathHandler = new DefaultODataPathHandler();
            var model       = GetEdmModel();

            config.MapHttpAttributeRoutes();
            var conventions = config.CreateODataDomainRoutingConventions <NorthwindDomainController>(model);
            var constraint  = new DefaultODataPathRouteConstraint(pathHandler, model, routeName, conventions);

            config.EnsureInitialized();
            var values = new Dictionary <string, object>
            {
                { ODataRouteConstants.ODataPath, entitySetName },
            };

            // Act
            var matched = constraint.Match(request, route: null, parameterName: null, values: values,
                                           routeDirection: HttpRouteDirection.UriResolution);

            // Assert
            Assert.True(matched);
            Assert.Equal(expectedControllerName, values[ODataRouteConstants.Controller]);
        }
        /// TODO GitHubIssue#51 : Support model lazy loading
        /// <summary>
        /// Maps the domain routes to the given domain controller.
        /// </summary>
        /// <typeparam name="TController">The domain controller.</typeparam>
        /// <param name="config">The <see cref="HttpConfiguration"/> instance.</param>
        /// <param name="routeName">The name of the route.</param>
        /// <param name="routePrefix">The prefix of the route.</param>
        /// <param name="domainFactory">The callback to create domain instances.</param>
        /// <param name="batchHandler">The handler for batch requests.</param>
        /// <returns>The task object containing the resulted <see cref="ODataRoute"/> instance.</returns>
        public static async Task <ODataRoute> MapODataDomainRoute <TController>(
            this HttpConfiguration config,
            string routeName,
            string routePrefix,
            Func <IDomain> domainFactory,
            ODataDomainBatchHandler batchHandler = null)
            where TController : ODataDomainController, new()
        {
            Ensure.NotNull(domainFactory, "domainFactory");

            using (var domain = domainFactory())
            {
                var model = await domain.GetModelAsync();

                model.EnsurePayloadValueConverter();
                var conventions = CreateODataDomainRoutingConventions <TController>(config, model);

                if (batchHandler != null && batchHandler.DomainFactory == null)
                {
                    batchHandler.DomainFactory = domainFactory;
                }

                var routes = config.Routes;
                routePrefix = RemoveTrailingSlash(routePrefix);

                if (batchHandler != null)
                {
                    batchHandler.ODataRouteName = routeName;
                    var batchTemplate = string.IsNullOrEmpty(routePrefix) ? ODataRouteConstants.Batch
                        : routePrefix + '/' + ODataRouteConstants.Batch;
                    routes.MapHttpBatchRoute(routeName + "Batch", batchTemplate, batchHandler);
                }

                DefaultODataPathHandler odataPathHandler = new DefaultODataPathHandler();

                var getResolverSettings = typeof(WebApiODataEx.HttpConfigurationExtensions)
                                          .GetMethod("GetResolverSettings", BindingFlags.NonPublic | BindingFlags.Static);

                if (getResolverSettings != null)
                {
                    var          resolveSettings = getResolverSettings.Invoke(null, new object[] { config });
                    PropertyInfo prop            = odataPathHandler
                                                   .GetType().GetProperty("ResolverSetttings", BindingFlags.NonPublic | BindingFlags.Instance);

                    if (null != prop && prop.CanWrite)
                    {
                        prop.SetValue(odataPathHandler, resolveSettings, null);
                    }

                    // In case WebAPI OData fix "ResolverSetttings" to "ResolverSettings".
                    // So we set both "ResolverSetttings" and "ResolverSettings".
                    prop = odataPathHandler
                           .GetType().GetProperty("ResolverSettings", BindingFlags.NonPublic | BindingFlags.Instance);
                    if (null != prop && prop.CanWrite)
                    {
                        prop.SetValue(odataPathHandler, resolveSettings, null);
                    }
                }

                var routeConstraint =
                    new DefaultODataPathRouteConstraint(odataPathHandler, model, routeName, conventions);
                var route = new ODataRoute(routePrefix, routeConstraint);
                routes.Add(routeName, route);
                return(route);
            }
        }