diff --git a/samples/RoutingSample.Web/RouteBuilderExtensions.cs b/samples/RoutingSample.Web/RouteBuilderExtensions.cs new file mode 100644 index 0000000000..52c57598fb --- /dev/null +++ b/samples/RoutingSample.Web/RouteBuilderExtensions.cs @@ -0,0 +1,32 @@ +using System; +using Microsoft.AspNet.Routing; + +namespace RoutingSample.Web +{ + public static class RouteBuilderExtensions + { + public static IRouteBuilder AddPrefixRoute(this IRouteBuilder routeBuilder, + string prefix) + { + if (routeBuilder.DefaultHandler == null) + { + throw new InvalidOperationException("DefaultHandler must be set."); + } + + if (routeBuilder.ServiceProvider == null) + { + throw new InvalidOperationException("ServiceProvider must be set."); + } + + return AddPrefixRoute(routeBuilder, prefix, routeBuilder.DefaultHandler); + } + + public static IRouteBuilder AddPrefixRoute(this IRouteBuilder routeBuilder, + string prefix, + IRouter handler) + { + routeBuilder.Routes.Add(new PrefixRoute(handler, prefix)); + return routeBuilder; + } + } +} \ No newline at end of file diff --git a/samples/RoutingSample.Web/RouteCollectionExtensions.cs b/samples/RoutingSample.Web/RouteCollectionExtensions.cs deleted file mode 100644 index d9d34d55fb..0000000000 --- a/samples/RoutingSample.Web/RouteCollectionExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using Microsoft.AspNet.Routing; - -namespace RoutingSample.Web -{ - public static class RouteCollectionExtensions - { - public static IRouteCollection AddPrefixRoute(this IRouteCollection routes, string prefix) - { - if (routes.DefaultHandler == null) - { - throw new ArgumentException("DefaultHandler must be set."); - } - - return AddPrefixRoute(routes, prefix, routes.DefaultHandler); - } - - public static IRouteCollection AddPrefixRoute(this IRouteCollection routes, string prefix, IRouter handler) - { - routes.Add(new PrefixRoute(handler, prefix)); - return routes; - } - } -} diff --git a/samples/RoutingSample.Web/RoutingSample.Web.kproj b/samples/RoutingSample.Web/RoutingSample.Web.kproj index 58cdf18b58..d22fc3b855 100644 --- a/samples/RoutingSample.Web/RoutingSample.Web.kproj +++ b/samples/RoutingSample.Web/RoutingSample.Web.kproj @@ -28,7 +28,7 @@ - + diff --git a/samples/RoutingSample.Web/Startup.cs b/samples/RoutingSample.Web/Startup.cs index fb3dc00172..9acde00e9b 100644 --- a/samples/RoutingSample.Web/Startup.cs +++ b/samples/RoutingSample.Web/Startup.cs @@ -1,7 +1,9 @@ +using System; using System.Text.RegularExpressions; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Routing; using Microsoft.AspNet.Routing.Constraints; +using Microsoft.Framework.DependencyInjection; namespace RoutingSample.Web { @@ -9,32 +11,46 @@ namespace RoutingSample.Web { public void Configure(IBuilder builder) { - var routes = new RouteCollection(); - builder.UseRouter(routes); + var collectionBuilder = new RouteBuilder(); var endpoint1 = new DelegateRouteEndpoint(async (context) => - await context.HttpContext.Response.WriteAsync( - "match1, route values -" + context.Values.Print())); + await context + .HttpContext + .Response + .WriteAsync( + "match1, route values -" + context.Values.Print())); + var endpoint2 = new DelegateRouteEndpoint(async (context) => - await context.HttpContext.Response.WriteAsync("Hello, World!")); + await context + .HttpContext + .Response + .WriteAsync("Hello, World!")); - routes.DefaultHandler = endpoint1; - routes.AddPrefixRoute("api/store"); + collectionBuilder.DefaultHandler = endpoint1; + collectionBuilder.ServiceProvider = builder.ApplicationServices; - routes.MapRoute("defaultRoute", "api/constraint/{controller}", null, new { controller = "my.*" }); - routes.MapRoute("regexStringRoute", - "api/rconstraint/{controller}", - new { foo = "Bar" }, - new { controller = new RegexConstraint("^(my.*)$") }); - routes.MapRoute("regexRoute", - "api/r2constraint/{controller}", - new { foo = "Bar2" }, - new { controller = new RegexConstraint(new Regex("^(my.*)$")) }); + collectionBuilder.AddPrefixRoute("api/store"); - routes.MapRoute("parameterConstraintRoute", "api/{controller}/{*extra}", new { controller = "Store" }); + collectionBuilder.MapRoute("defaultRoute", + "api/constraint/{controller}", + null, + new { controller = "my.*" }); + collectionBuilder.MapRoute("regexStringRoute", + "api/rconstraint/{controller}", + new { foo = "Bar" }, + new { controller = new RegexConstraint("^(my.*)$") }); + collectionBuilder.MapRoute("regexRoute", + "api/r2constraint/{controller}", + new { foo = "Bar2" }, + new { controller = new RegexConstraint(new Regex("^(my.*)$")) }); - routes.AddPrefixRoute("hello/world", endpoint2); - routes.AddPrefixRoute("", endpoint2); + collectionBuilder.MapRoute("parameterConstraintRoute", + "api/{controller}/{*extra}", + new { controller = "Store" }); + + collectionBuilder.AddPrefixRoute("hello/world", endpoint2); + collectionBuilder.AddPrefixRoute("", endpoint2); + builder.UseRouter(collectionBuilder.Build()); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Routing/IRouteBuilder.cs b/src/Microsoft.AspNet.Routing/IRouteBuilder.cs new file mode 100644 index 0000000000..7da8c5b61d --- /dev/null +++ b/src/Microsoft.AspNet.Routing/IRouteBuilder.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; + +namespace Microsoft.AspNet.Routing +{ + public interface IRouteBuilder + { + IRouter DefaultHandler { get; } + + IServiceProvider ServiceProvider { get; } + + IList Routes { get; } + + IRouter Build(); + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Routing/IRouteCollection.cs b/src/Microsoft.AspNet.Routing/IRouteCollection.cs index 18b5820d94..6cf93ce564 100644 --- a/src/Microsoft.AspNet.Routing/IRouteCollection.cs +++ b/src/Microsoft.AspNet.Routing/IRouteCollection.cs @@ -5,10 +5,6 @@ namespace Microsoft.AspNet.Routing { public interface IRouteCollection : IRouter { - IRouter DefaultHandler { get; set; } - - IInlineConstraintResolver InlineConstraintResolver { get; set; } - void Add(IRouter router); } } diff --git a/src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj b/src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj index f82446805f..738877d0b7 100644 --- a/src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj +++ b/src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj @@ -29,13 +29,15 @@ + - + + diff --git a/src/Microsoft.AspNet.Routing/RouteBuilder.cs b/src/Microsoft.AspNet.Routing/RouteBuilder.cs new file mode 100644 index 0000000000..6d04899e93 --- /dev/null +++ b/src/Microsoft.AspNet.Routing/RouteBuilder.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; + +namespace Microsoft.AspNet.Routing +{ + public class RouteBuilder : IRouteBuilder + { + public RouteBuilder() + { + Routes = new List(); + } + + public IRouter DefaultHandler { get; set; } + + public IServiceProvider ServiceProvider { get; set; } + + public IList Routes + { + get; + private set; + } + + public IRouter Build() + { + var routeCollection = new RouteCollection(); + + foreach (var route in Routes) + { + routeCollection.Add(route); + } + + return routeCollection; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Routing/RouteBuilderExtensions.cs b/src/Microsoft.AspNet.Routing/RouteBuilderExtensions.cs new file mode 100644 index 0000000000..0905d31114 --- /dev/null +++ b/src/Microsoft.AspNet.Routing/RouteBuilderExtensions.cs @@ -0,0 +1,109 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using Microsoft.AspNet.Routing.Template; +using Microsoft.Framework.DependencyInjection; + +namespace Microsoft.AspNet.Routing +{ + public static class RouteBuilderExtensions + { + public static IRouteBuilder MapRoute(this IRouteBuilder routeCollectionBuilder, + string name, + string template) + { + MapRoute(routeCollectionBuilder, name, template, defaults: null); + return routeCollectionBuilder; + } + + public static IRouteBuilder MapRoute(this IRouteBuilder routeCollectionBuilder, + string name, + string template, + object defaults) + { + MapRoute(routeCollectionBuilder, name, template, new RouteValueDictionary(defaults)); + return routeCollectionBuilder; + } + + public static IRouteBuilder MapRoute(this IRouteBuilder routeCollectionBuilder, + string name, + string template, + IDictionary defaults) + { + if (routeCollectionBuilder.DefaultHandler == null) + { + throw new InvalidOperationException(Resources.DefaultHandler_MustBeSet); + } + + var inlineConstraintResolver = routeCollectionBuilder + .ServiceProvider + .GetService(); + + routeCollectionBuilder.Routes.Add(new TemplateRoute(routeCollectionBuilder.DefaultHandler, + name, + template, + defaults, + constraints: null, + inlineConstraintResolver: inlineConstraintResolver)); + return routeCollectionBuilder; + } + + public static IRouteBuilder MapRoute(this IRouteBuilder routeCollectionBuilder, + string name, + string template, + object defaults, + object constraints) + { + MapRoute(routeCollectionBuilder, + name, + template, + new RouteValueDictionary(defaults), + new RouteValueDictionary(constraints)); + return routeCollectionBuilder; + } + + public static IRouteBuilder MapRoute(this IRouteBuilder routeCollectionBuilder, + string name, + string template, + object defaults, + IDictionary constraints) + { + MapRoute(routeCollectionBuilder, name, template, new RouteValueDictionary(defaults), constraints); + return routeCollectionBuilder; + } + + public static IRouteBuilder MapRoute(this IRouteBuilder routeCollectionBuilder, + string name, + string template, + IDictionary defaults, object constraints) + { + MapRoute(routeCollectionBuilder, name, template, defaults, new RouteValueDictionary(constraints)); + return routeCollectionBuilder; + } + + public static IRouteBuilder MapRoute(this IRouteBuilder routeCollectionBuilder, + string name, + string template, + IDictionary defaults, + IDictionary constraints) + { + if (routeCollectionBuilder.DefaultHandler == null) + { + throw new InvalidOperationException(Resources.DefaultHandler_MustBeSet); + } + + var inlineConstraintResolver = routeCollectionBuilder + .ServiceProvider + .GetService(); + routeCollectionBuilder.Routes.Add(new TemplateRoute(routeCollectionBuilder.DefaultHandler, + name, + template, + defaults, + constraints, + inlineConstraintResolver)); + return routeCollectionBuilder; + } + } +} diff --git a/src/Microsoft.AspNet.Routing/RouteCollection.cs b/src/Microsoft.AspNet.Routing/RouteCollection.cs index b14183046a..682a96649b 100644 --- a/src/Microsoft.AspNet.Routing/RouteCollection.cs +++ b/src/Microsoft.AspNet.Routing/RouteCollection.cs @@ -24,10 +24,6 @@ namespace Microsoft.AspNet.Routing get { return _routes.Count; } } - public IRouter DefaultHandler { get; set; } - - public IInlineConstraintResolver InlineConstraintResolver { get; set; } - public void Add([NotNull] IRouter router) { var namedRouter = router as INamedRouter; diff --git a/src/Microsoft.AspNet.Routing/RouteCollectionExtensions.cs b/src/Microsoft.AspNet.Routing/RouteCollectionExtensions.cs deleted file mode 100644 index 5b17ea3e44..0000000000 --- a/src/Microsoft.AspNet.Routing/RouteCollectionExtensions.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using Microsoft.AspNet.Routing.Template; - -namespace Microsoft.AspNet.Routing -{ - public static class RouteCollectionExtensions - { - public static IRouteCollection MapRoute(this IRouteCollection routes, string name, string template) - { - MapRoute(routes, name, template, defaults: null); - return routes; - } - - public static IRouteCollection MapRoute(this IRouteCollection routes, string name, string template, - object defaults) - { - MapRoute(routes, name, template, new RouteValueDictionary(defaults)); - return routes; - } - - public static IRouteCollection MapRoute(this IRouteCollection routes, string name, string template, - IDictionary defaults) - { - if (routes.DefaultHandler == null) - { - throw new InvalidOperationException(Resources.DefaultHandler_MustBeSet); - } - - routes.Add(new TemplateRoute(routes.DefaultHandler, - name, - template, - defaults, - constraints: null, - inlineConstraintResolver: routes.InlineConstraintResolver)); - return routes; - } - - public static IRouteCollection MapRoute(this IRouteCollection routes, string name, string template, - object defaults, object constraints) - { - MapRoute(routes, - name, - template, - new RouteValueDictionary(defaults), - new RouteValueDictionary(constraints)); - return routes; - } - - public static IRouteCollection MapRoute(this IRouteCollection routes, string name, string template, - object defaults, IDictionary constraints) - { - MapRoute(routes, name, template, new RouteValueDictionary(defaults), constraints); - return routes; - } - - public static IRouteCollection MapRoute(this IRouteCollection routes, string name, string template, - IDictionary defaults, object constraints) - { - MapRoute(routes, name, template, defaults, new RouteValueDictionary(constraints)); - return routes; - } - - public static IRouteCollection MapRoute(this IRouteCollection routes, - string name, - string template, - IDictionary defaults, - IDictionary constraints) - { - if (routes.DefaultHandler == null) - { - throw new InvalidOperationException(Resources.DefaultHandler_MustBeSet); - } - - routes.Add(new TemplateRoute(routes.DefaultHandler, - name, - template, - defaults, - constraints, - routes.InlineConstraintResolver)); - return routes; - } - } -} diff --git a/src/Microsoft.AspNet.Routing/Template/TemplateRoute.cs b/src/Microsoft.AspNet.Routing/Template/TemplateRoute.cs index 3979ddf413..c59a391afa 100644 --- a/src/Microsoft.AspNet.Routing/Template/TemplateRoute.cs +++ b/src/Microsoft.AspNet.Routing/Template/TemplateRoute.cs @@ -209,4 +209,4 @@ namespace Microsoft.AspNet.Routing.Template } } } -} \ No newline at end of file +} diff --git a/src/Microsoft.AspNet.Routing/project.json b/src/Microsoft.AspNet.Routing/project.json index b188d44482..44b3f36a4f 100644 --- a/src/Microsoft.AspNet.Routing/project.json +++ b/src/Microsoft.AspNet.Routing/project.json @@ -1,7 +1,8 @@ { "version": "0.1-alpha-*", "dependencies": { - "Microsoft.AspNet.Http": "0.1-alpha-*" + "Microsoft.AspNet.Http": "0.1-alpha-*", + "Microsoft.Framework.DependencyInjection" : "0.1-alpha-*" }, "configurations": { "net45": {}, diff --git a/test/Microsoft.AspNet.Routing.Tests/Template/TemplateRouteTests.cs b/test/Microsoft.AspNet.Routing.Tests/Template/TemplateRouteTests.cs index 70efab66f1..f4c8f37536 100644 --- a/test/Microsoft.AspNet.Routing.Tests/Template/TemplateRouteTests.cs +++ b/test/Microsoft.AspNet.Routing.Tests/Template/TemplateRouteTests.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Routing.Constraints; using Microsoft.AspNet.Testing; +using Microsoft.Framework.DependencyInjection; using Moq; using Xunit; @@ -391,11 +392,10 @@ namespace Microsoft.AspNet.Routing.Template.Tests public void RegisteringRouteWithInvalidConstraints_Throws() { // Arrange - var collection = new RouteCollection(); - collection.DefaultHandler = new Mock().Object; + var routeBuilder = CreateRouteBuilder(); // Assert - ExceptionAssert.Throws(() => collection.MapRoute("mockName", + ExceptionAssert.Throws(() => routeBuilder.MapRoute("mockName", "{controller}/{action}", defaults: null, constraints: new { controller = "a.*", action = new Object() }), @@ -408,17 +408,16 @@ namespace Microsoft.AspNet.Routing.Template.Tests public void RegisteringRouteWithTwoConstraints() { // Arrange - var collection = new RouteCollection(); - collection.DefaultHandler = new Mock().Object; + var routeBuilder = CreateRouteBuilder(); var mockConstraint = new Mock().Object; - collection.MapRoute("mockName", + routeBuilder.MapRoute("mockName", "{controller}/{action}", defaults: null, constraints: new { controller = "a.*", action = mockConstraint }); - var constraints = ((TemplateRoute)collection[0]).Constraints; + var constraints = ((TemplateRoute)routeBuilder.Routes[0]).Constraints; // Assert Assert.Equal(2, constraints.Count); @@ -430,18 +429,16 @@ namespace Microsoft.AspNet.Routing.Template.Tests public void RegisteringRouteWithOneInlineConstraintAndOneUsingConstraintArgument() { // Arrange - var collection = new RouteCollection(); - collection.DefaultHandler = new Mock().Object; - collection.InlineConstraintResolver = new DefaultInlineConstraintResolver(); + var routeBuilder = CreateRouteBuilder(); - collection.MapRoute("mockName", + // Act + routeBuilder.MapRoute("mockName", "{controller}/{action}/{id:int}", defaults: null, constraints: new { id = "1*" }); - var constraints = ((TemplateRoute)collection[0]).Constraints; - // Assert + var constraints = ((TemplateRoute)routeBuilder.Routes[0]).Constraints; Assert.Equal(1, constraints.Count); var constraint = (CompositeRouteConstraint)constraints["id"]; Assert.IsType(constraint); @@ -453,18 +450,16 @@ namespace Microsoft.AspNet.Routing.Template.Tests public void RegisteringRoute_WithOneInlineConstraint_AddsItToConstraintCollection() { // Arrange - var collection = new RouteCollection(); - collection.DefaultHandler = new Mock().Object; - collection.InlineConstraintResolver = new DefaultInlineConstraintResolver(); + var routeBuilder = CreateRouteBuilder(); - collection.MapRoute("mockName", + // Act + routeBuilder.MapRoute("mockName", "{controller}/{action}/{id:int}", defaults: null, constraints: null); - var constraints = ((TemplateRoute)collection[0]).Constraints; - // Assert + var constraints = ((TemplateRoute)routeBuilder.Routes[0]).Constraints; Assert.Equal(1, constraints.Count); Assert.IsType(constraints["id"]); } @@ -473,13 +468,12 @@ namespace Microsoft.AspNet.Routing.Template.Tests public void RegisteringRouteWithRouteName_WithNullDefaults_AddsTheRoute() { // Arrange - var collection = new RouteCollection(); - collection.DefaultHandler = new Mock().Object; + var routeBuilder = CreateRouteBuilder(); - collection.MapRoute(name: "RouteName", template: "{controller}/{action}", defaults: null); + routeBuilder.MapRoute(name: "RouteName", template: "{controller}/{action}", defaults: null); // Act - var name = ((TemplateRoute)collection[0]).Name; + var name = ((TemplateRoute)routeBuilder.Routes[0]).Name; // Assert Assert.Equal("RouteName", name); @@ -489,16 +483,15 @@ namespace Microsoft.AspNet.Routing.Template.Tests public void RegisteringRouteWithRouteName_WithNullDefaultsAndConstraints_AddsTheRoute() { // Arrange - var collection = new RouteCollection(); - collection.DefaultHandler = new Mock().Object; + var routeBuilder = CreateRouteBuilder(); - collection.MapRoute(name: "RouteName", + routeBuilder.MapRoute(name: "RouteName", template: "{controller}/{action}", defaults: null, constraints: null); // Act - var name = ((TemplateRoute)collection[0]).Name; + var name = ((TemplateRoute)routeBuilder.Routes[0]).Name; // Assert Assert.Equal("RouteName", name); @@ -506,6 +499,20 @@ namespace Microsoft.AspNet.Routing.Template.Tests #endregion + private static IRouteBuilder CreateRouteBuilder() + { + var routeBuilder = new RouteBuilder(); + + routeBuilder.DefaultHandler = new Mock().Object; + + var serviceProviderMock = new Mock(); + serviceProviderMock.Setup(o => o.GetService(typeof(IInlineConstraintResolver))) + .Returns(new DefaultInlineConstraintResolver()); + routeBuilder.ServiceProvider = serviceProviderMock.Object; + + return routeBuilder; + } + private static TemplateRoute CreateRoute(string template, bool accept = true) { return new TemplateRoute(CreateTarget(accept), template, new DefaultInlineConstraintResolver());