From a499d4a92a0d0a6eabf0b736d5bc399e67b3c1da Mon Sep 17 00:00:00 2001 From: harshgMSFT Date: Thu, 5 Jun 2014 12:24:52 -0700 Subject: [PATCH] Routing DI Changes II : Adding services for routing. --- samples/RoutingSample.Web/Startup.cs | 53 +++++++++++-------- samples/RoutingSample.Web/project.json | 4 +- .../DefaultInlineConstraintResolver.cs | 27 +++------- .../Microsoft.AspNet.Routing.kproj | 6 ++- .../Properties/Resources.Designer.cs | 20 ++++++- src/Microsoft.AspNet.Routing/Resources.resx | 3 ++ src/Microsoft.AspNet.Routing/RouteOptions.cs | 42 +++++++++++++++ .../RoutingServices.cs | 28 ++++++++++ src/Microsoft.AspNet.Routing/project.json | 4 +- .../DefaultInlineConstraintResolverTest.cs | 39 +++++++++++--- .../InlineRouteParameterParserTests.cs | 26 ++++++--- .../RouteOptionsTests.cs | 23 ++++++++ .../Template/TemplateBinderTests.cs | 20 ++++++- .../Template/TemplateMatcherTests.cs | 21 +++++++- .../Template/TemplateParserTests.cs | 18 ++++++- .../Template/TemplateRouteTests.cs | 19 +++++-- 16 files changed, 280 insertions(+), 73 deletions(-) create mode 100644 src/Microsoft.AspNet.Routing/RouteOptions.cs create mode 100644 src/Microsoft.AspNet.Routing/RoutingServices.cs create mode 100644 test/Microsoft.AspNet.Routing.Tests/RouteOptionsTests.cs diff --git a/samples/RoutingSample.Web/Startup.cs b/samples/RoutingSample.Web/Startup.cs index d24a679e6d..6c4891ebbb 100644 --- a/samples/RoutingSample.Web/Startup.cs +++ b/samples/RoutingSample.Web/Startup.cs @@ -1,9 +1,12 @@ using System; +using System.Collections.Generic; using System.Text.RegularExpressions; using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; using Microsoft.AspNet.Routing; using Microsoft.AspNet.Routing.Constraints; using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; namespace RoutingSample.Web { @@ -11,7 +14,10 @@ namespace RoutingSample.Web { public void Configure(IBuilder builder) { - var collectionBuilder = new RouteBuilder(); + builder.UseServices(services => + { + services.Add(RoutingServices.GetDefaultServices()); + }); var endpoint1 = new DelegateRouteEndpoint(async (context) => await context @@ -20,37 +26,38 @@ namespace RoutingSample.Web .WriteAsync( "match1, route values -" + context.RouteData.Values.Print())); - var endpoint2 = new DelegateRouteEndpoint(async (context) => + var endpoint2 = new DelegateRouteEndpoint(async (context) => await context .HttpContext .Response .WriteAsync("Hello, World!")); - collectionBuilder.DefaultHandler = endpoint1; - collectionBuilder.ServiceProvider = builder.ApplicationServices; + var routeBuilder = new RouteBuilder(); + routeBuilder.DefaultHandler = endpoint1; + routeBuilder.ServiceProvider = builder.ApplicationServices; - collectionBuilder.AddPrefixRoute("api/store"); + routeBuilder.AddPrefixRoute("api/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.*)$")) }); + routeBuilder.MapRoute("defaultRoute", + "api/constraint/{controller}", + null, + new { controller = "my.*" }); + routeBuilder.MapRoute("regexStringRoute", + "api/rconstraint/{controller}", + new { foo = "Bar" }, + new { controller = new RegexConstraint("^(my.*)$") }); + routeBuilder.MapRoute("regexRoute", + "api/r2constraint/{controller}", + new { foo = "Bar2" }, + new { controller = new RegexConstraint(new Regex("^(my.*)$")) }); - collectionBuilder.MapRoute("parameterConstraintRoute", - "api/{controller}/{*extra}", - new { controller = "Store" }); + routeBuilder.MapRoute("parameterConstraintRoute", + "api/{controller}/{*extra}", + new { controller = "Store" }); - collectionBuilder.AddPrefixRoute("hello/world", endpoint2); - collectionBuilder.AddPrefixRoute("", endpoint2); - builder.UseRouter(collectionBuilder.Build()); + routeBuilder.AddPrefixRoute("hello/world", endpoint2); + routeBuilder.AddPrefixRoute("", endpoint2); + builder.UseRouter(routeBuilder.Build()); } } } \ No newline at end of file diff --git a/samples/RoutingSample.Web/project.json b/samples/RoutingSample.Web/project.json index 4871720301..f478d58dde 100644 --- a/samples/RoutingSample.Web/project.json +++ b/samples/RoutingSample.Web/project.json @@ -2,7 +2,9 @@ "version": "0.1-alpha-*", "dependencies": { "Helios": "0.1-alpha-*", - "Microsoft.AspNet.Routing" : "" + "Microsoft.AspNet.Routing" : "", + "Microsoft.AspNet.RequestContainer": "0.1-alpha-*", + "Microsoft.Framework.OptionsModel": "0.1-alpha-*" }, "configurations": { "net45": { }, diff --git a/src/Microsoft.AspNet.Routing/DefaultInlineConstraintResolver.cs b/src/Microsoft.AspNet.Routing/DefaultInlineConstraintResolver.cs index fc04fff664..8f132778f9 100644 --- a/src/Microsoft.AspNet.Routing/DefaultInlineConstraintResolver.cs +++ b/src/Microsoft.AspNet.Routing/DefaultInlineConstraintResolver.cs @@ -6,7 +6,8 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; -using Microsoft.AspNet.Routing.Constraints; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Routing { @@ -17,26 +18,14 @@ namespace Microsoft.AspNet.Routing /// public class DefaultInlineConstraintResolver : IInlineConstraintResolver { - private readonly IDictionary _inlineConstraintMap = GetDefaultConstraintMap(); + private readonly IDictionary _inlineConstraintMap; + private readonly IServiceProvider _serviceProvider; - /// - /// Gets the mutable dictionary that maps constraint keys to a particular constraint type. - /// - public IDictionary ConstraintMap + public DefaultInlineConstraintResolver(IServiceProvider serviceProvider, + IOptionsAccessor routeOptions) { - get - { - return _inlineConstraintMap; - } - } - - private static IDictionary GetDefaultConstraintMap() - { - return new Dictionary(StringComparer.OrdinalIgnoreCase) - { - // Type-specific constraints - { "int", typeof(IntRouteConstraint) }, - }; + _serviceProvider = serviceProvider; + _inlineConstraintMap = routeOptions.Options.ConstraintMap; } /// diff --git a/src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj b/src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj index fd6d50748f..bddc4bd9d9 100644 --- a/src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj +++ b/src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj @@ -18,7 +18,9 @@ - + + Designer + @@ -30,6 +32,7 @@ + @@ -43,6 +46,7 @@ + diff --git a/src/Microsoft.AspNet.Routing/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Routing/Properties/Resources.Designer.cs index b226fdddb2..d3acb37cd9 100644 --- a/src/Microsoft.AspNet.Routing/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Routing/Properties/Resources.Designer.cs @@ -10,6 +10,22 @@ namespace Microsoft.AspNet.Routing private static readonly ResourceManager _resourceManager = new ResourceManager("Microsoft.AspNet.Routing.Resources", typeof(Resources).GetTypeInfo().Assembly); + /// + /// The '{0}' property of '{1}' must not be null. + /// + internal static string PropertyOfTypeCannotBeNull + { + get { return GetString("PropertyOfTypeCannotBeNull"); } + } + + /// + /// The '{0}' property of '{1}' must not be null. + /// + internal static string FormatPropertyOfTypeCannotBeNull(object p0, object p1) + { + return string.Format(CultureInfo.CurrentCulture, GetString("PropertyOfTypeCannotBeNull"), p0, p1); + } + /// /// The supplied route name '{0}' is ambiguous and matched more than one route. /// @@ -123,7 +139,7 @@ namespace Microsoft.AspNet.Routing } /// - /// The route parameter '{0}' has both an inline deafult value and an explicit default value specified. A route parameter cannot contain an inline default value when a default value is specified explicitly. Consider removing one of them. + /// The route parameter '{0}' has both an inline default value and an explicit default value specified. A route parameter cannot contain an inline default value when a default value is specified explicitly. Consider removing one of them. /// internal static string TemplateRoute_CannotHaveDefaultValueSpecifiedInlineAndExplicitly { @@ -131,7 +147,7 @@ namespace Microsoft.AspNet.Routing } /// - /// The route parameter '{0}' has both an inline deafult value and an explicit default value specified. A route parameter cannot contain an inline default value when a default value is specified explicitly. Consider removing one of them. + /// The route parameter '{0}' has both an inline default value and an explicit default value specified. A route parameter cannot contain an inline default value when a default value is specified explicitly. Consider removing one of them. /// internal static string FormatTemplateRoute_CannotHaveDefaultValueSpecifiedInlineAndExplicitly(object p0) { diff --git a/src/Microsoft.AspNet.Routing/Resources.resx b/src/Microsoft.AspNet.Routing/Resources.resx index ba89de6413..cea33cad4e 100644 --- a/src/Microsoft.AspNet.Routing/Resources.resx +++ b/src/Microsoft.AspNet.Routing/Resources.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + The '{0}' property of '{1}' must not be null. + The supplied route name '{0}' is ambiguous and matched more than one route. diff --git a/src/Microsoft.AspNet.Routing/RouteOptions.cs b/src/Microsoft.AspNet.Routing/RouteOptions.cs new file mode 100644 index 0000000000..f0562176ed --- /dev/null +++ b/src/Microsoft.AspNet.Routing/RouteOptions.cs @@ -0,0 +1,42 @@ +// 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.Constraints; + +namespace Microsoft.AspNet.Routing +{ + public class RouteOptions + { + private IDictionary _constraintTypeMap = GetDefaultConstraintMap(); + + public IDictionary ConstraintMap + { + get + { + return _constraintTypeMap; + } + set + { + if(value == null) + { + throw new ArgumentNullException("value", + Resources.FormatPropertyOfTypeCannotBeNull( + "ConstraintMap", typeof(RouteOptions))); + } + + _constraintTypeMap = value; + } + } + + private static IDictionary GetDefaultConstraintMap() + { + return new Dictionary(StringComparer.OrdinalIgnoreCase) + { + // Type-specific constraints + { "int", typeof(IntRouteConstraint) }, + }; + } + } +} diff --git a/src/Microsoft.AspNet.Routing/RoutingServices.cs b/src/Microsoft.AspNet.Routing/RoutingServices.cs new file mode 100644 index 0000000000..bd4035bd24 --- /dev/null +++ b/src/Microsoft.AspNet.Routing/RoutingServices.cs @@ -0,0 +1,28 @@ +// 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.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Routing; +using Microsoft.Framework.ConfigurationModel; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.DependencyInjection.NestedProviders; + +namespace Microsoft.AspNet.Routing +{ + public class RoutingServices + { + public static IEnumerable GetDefaultServices() + { + return GetDefaultServices(new Configuration()); + } + + public static IEnumerable GetDefaultServices(IConfiguration configuration) + { + var describe = new ServiceDescriber(configuration); + + yield return describe.Transient(); + } + } +} diff --git a/src/Microsoft.AspNet.Routing/project.json b/src/Microsoft.AspNet.Routing/project.json index cc5e35b3ff..9cfca79e48 100644 --- a/src/Microsoft.AspNet.Routing/project.json +++ b/src/Microsoft.AspNet.Routing/project.json @@ -5,7 +5,9 @@ }, "dependencies": { "Microsoft.AspNet.Http": "0.1-alpha-*", - "Microsoft.Framework.DependencyInjection" : "0.1-alpha-*" + "Microsoft.Framework.DependencyInjection" : "0.1-alpha-*", + "Microsoft.AspNet.RequestContainer": "0.1-alpha-*", + "Microsoft.Framework.OptionsModel": "0.1-alpha-*" }, "configurations": { "net45": {}, diff --git a/test/Microsoft.AspNet.Routing.Tests/DefaultInlineConstraintResolverTest.cs b/test/Microsoft.AspNet.Routing.Tests/DefaultInlineConstraintResolverTest.cs index 5e60434e23..1d387a81a3 100644 --- a/test/Microsoft.AspNet.Routing.Tests/DefaultInlineConstraintResolverTest.cs +++ b/test/Microsoft.AspNet.Routing.Tests/DefaultInlineConstraintResolverTest.cs @@ -1,10 +1,14 @@ // 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. +#if NET45 using System; using System.Collections.Generic; using Microsoft.AspNet.Http; using Microsoft.AspNet.Routing.Constraints; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.OptionsModel; +using Moq; using Xunit; namespace Microsoft.AspNet.Routing.Tests @@ -14,8 +18,12 @@ namespace Microsoft.AspNet.Routing.Tests [Fact] public void ResolveConstraint_IntConstraint_ResolvesCorrectly() { - // Arrange & Act - var constraint = new DefaultInlineConstraintResolver().ResolveConstraint("int"); + // Arrange + var routeOptions = new RouteOptions(); + var constraintResolver = GetInlineConstraintResolver(routeOptions); + + // Act + var constraint = constraintResolver.ResolveConstraint("int"); // Assert Assert.IsType(constraint); @@ -24,9 +32,13 @@ namespace Microsoft.AspNet.Routing.Tests [Fact] public void ResolveConstraint_IntConstraintWithArgument_Throws() { + // Arrange + var routeOptions = new RouteOptions(); + var constraintResolver = GetInlineConstraintResolver(routeOptions); + // Act & Assert var ex = Assert.Throws( - () => new DefaultInlineConstraintResolver().ResolveConstraint("int(5)")); + () => constraintResolver.ResolveConstraint("int(5)")); Assert.Equal("Could not find a constructor for constraint type 'IntRouteConstraint'"+ " with the following number of parameters: 1.", ex.Message); @@ -36,8 +48,9 @@ namespace Microsoft.AspNet.Routing.Tests public void ResolveConstraint_SupportsCustomConstraints() { // Arrange - var resolver = new DefaultInlineConstraintResolver(); - resolver.ConstraintMap.Add("custom", typeof(CustomRouteConstraint)); + var routeOptions = new RouteOptions(); + routeOptions.ConstraintMap.Add("custom", typeof(CustomRouteConstraint)); + var resolver = GetInlineConstraintResolver(routeOptions); // Act var constraint = resolver.ResolveConstraint("custom(argument)"); @@ -50,8 +63,9 @@ namespace Microsoft.AspNet.Routing.Tests public void ResolveConstraint_CustomConstraintThatDoesNotImplementIRouteConstraint_Throws() { // Arrange - var resolver = new DefaultInlineConstraintResolver(); - resolver.ConstraintMap.Add("custom", typeof(string)); + var routeOptions = new RouteOptions(); + routeOptions.ConstraintMap.Add("custom", typeof(string)); + var resolver = GetInlineConstraintResolver(routeOptions); // Act & Assert var ex = Assert.Throws(() => resolver.ResolveConstraint("custom")); @@ -60,6 +74,16 @@ namespace Microsoft.AspNet.Routing.Tests ex.Message); } + private IInlineConstraintResolver GetInlineConstraintResolver(RouteOptions routeOptions) + { + var optionsAccessor = new Mock>(); + optionsAccessor.SetupGet(o => o.Options).Returns(routeOptions); + var serviceProvider = new Mock(); + serviceProvider.Setup(o => o.GetService(It.Is(type => type == typeof(ITypeActivator)))) + .Returns(new TypeActivator()); + return new DefaultInlineConstraintResolver(serviceProvider.Object, optionsAccessor.Object); + } + private class CustomRouteConstraint : IRouteConstraint { public CustomRouteConstraint(string pattern) @@ -79,3 +103,4 @@ namespace Microsoft.AspNet.Routing.Tests } } } +#endif diff --git a/test/Microsoft.AspNet.Routing.Tests/InlineRouteParameterParserTests.cs b/test/Microsoft.AspNet.Routing.Tests/InlineRouteParameterParserTests.cs index 20bf7be646..28c22bc164 100644 --- a/test/Microsoft.AspNet.Routing.Tests/InlineRouteParameterParserTests.cs +++ b/test/Microsoft.AspNet.Routing.Tests/InlineRouteParameterParserTests.cs @@ -7,6 +7,9 @@ using System.Linq; using Microsoft.AspNet.Http; using Microsoft.AspNet.Routing.Constraints; using Microsoft.AspNet.Routing.Template; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.DependencyInjection.Fallback; +using Microsoft.Framework.OptionsModel; using Xunit; namespace Microsoft.AspNet.Routing.Tests @@ -164,7 +167,7 @@ namespace Microsoft.AspNet.Routing.Tests [Fact] public void ParseRouteParameter_ConstraintWithCommaInPattern_PatternIsParsedCorrectly() { - // Arrange + // Arrange & Act var templatePart = ParseParameter(@"param:test(\w,\w)"); // Assert @@ -267,22 +270,29 @@ namespace Microsoft.AspNet.Routing.Tests private TemplatePart ParseParameter(string routeParameter) { - var constraintResolver = new DefaultInlineConstraintResolver(); - - // TODO: This will be removed once this is supported in product code. - constraintResolver.ConstraintMap.Add("test", typeof(TestRouteConstraint)); + var constraintResolver = GetConstraintResolver(); var templatePart = InlineRouteParameterParser.ParseRouteParameter(routeParameter, constraintResolver); return templatePart; } private static Template.Template ParseRouteTemplate(string template) { - var constraintResolver = new DefaultInlineConstraintResolver(); - - constraintResolver.ConstraintMap.Add("test", typeof(TestRouteConstraint)); + var constraintResolver = GetConstraintResolver(); return TemplateParser.Parse(template, constraintResolver); } + private static IInlineConstraintResolver GetConstraintResolver() + { + var services = new ServiceCollection { OptionsServices.GetDefaultServices() }; + services.SetupOptions(options => + options + .ConstraintMap + .Add("test", typeof(TestRouteConstraint))); + var serviceProvider = services.BuildServiceProvider(); + var accessor = serviceProvider.GetService>(); + return new DefaultInlineConstraintResolver(serviceProvider, accessor); + } + private class TestRouteConstraint : IRouteConstraint { public TestRouteConstraint(string pattern) diff --git a/test/Microsoft.AspNet.Routing.Tests/RouteOptionsTests.cs b/test/Microsoft.AspNet.Routing.Tests/RouteOptionsTests.cs new file mode 100644 index 0000000000..37cdb3ca99 --- /dev/null +++ b/test/Microsoft.AspNet.Routing.Tests/RouteOptionsTests.cs @@ -0,0 +1,23 @@ +// 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 Xunit; + +namespace Microsoft.AspNet.Routing.Tests +{ + public class RouteOptionsTests + { + [Fact] + public void ConstraintMap_SettingNullValue_Throws() + { + // Arrange + var options = new RouteOptions(); + + // Act & Assert + var ex = Assert.Throws(() => options.ConstraintMap = null); + Assert.Equal("The 'ConstraintMap' property of 'Microsoft.AspNet.Routing.RouteOptions' must not be null." + + "\r\nParameter name: value", ex.Message); + } + } +} diff --git a/test/Microsoft.AspNet.Routing.Tests/Template/TemplateBinderTests.cs b/test/Microsoft.AspNet.Routing.Tests/Template/TemplateBinderTests.cs index aaacb0a17a..ae5fb835f0 100644 --- a/test/Microsoft.AspNet.Routing.Tests/Template/TemplateBinderTests.cs +++ b/test/Microsoft.AspNet.Routing.Tests/Template/TemplateBinderTests.cs @@ -1,15 +1,22 @@ // 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. +#if NET45 using System; using System.Collections.Generic; using System.Linq; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.DependencyInjection.Fallback; +using Microsoft.Framework.OptionsModel; +using Moq; using Xunit; namespace Microsoft.AspNet.Routing.Template.Tests { public class TemplateBinderTests { + private static IInlineConstraintResolver _inlineConstraintResolver = GetInlineConstraintResolver(); + public static IEnumerable EmptyAndNullDefaultValues { get @@ -127,7 +134,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests string expected) { // Arrange - var binder = new TemplateBinder(TemplateParser.Parse(template, new DefaultInlineConstraintResolver()), + var binder = new TemplateBinder(TemplateParser.Parse(template, _inlineConstraintResolver), defaults); // Act & Assert @@ -961,7 +968,7 @@ namespace Microsoft.AspNet.Routing.Template.Tests string expected) { // Arrange - var binder = new TemplateBinder(TemplateParser.Parse(template, new DefaultInlineConstraintResolver()), defaults); + var binder = new TemplateBinder(TemplateParser.Parse(template, _inlineConstraintResolver), defaults); // Act & Assert var acceptedValues = binder.GetAcceptedValues(ambientValues, values); @@ -1025,6 +1032,14 @@ namespace Microsoft.AspNet.Routing.Template.Tests expected); } + private static IInlineConstraintResolver GetInlineConstraintResolver() + { + var services = new ServiceCollection { OptionsServices.GetDefaultServices() }; + var serviceProvider = services.BuildServiceProvider(); + var accessor = serviceProvider.GetService>(); + return new DefaultInlineConstraintResolver(serviceProvider, accessor); + } + private class PathAndQuery { public PathAndQuery(string uri) @@ -1053,3 +1068,4 @@ namespace Microsoft.AspNet.Routing.Template.Tests } } } +#endif \ No newline at end of file diff --git a/test/Microsoft.AspNet.Routing.Tests/Template/TemplateMatcherTests.cs b/test/Microsoft.AspNet.Routing.Tests/Template/TemplateMatcherTests.cs index 3a8eb4bb38..11c25b5478 100644 --- a/test/Microsoft.AspNet.Routing.Tests/Template/TemplateMatcherTests.cs +++ b/test/Microsoft.AspNet.Routing.Tests/Template/TemplateMatcherTests.cs @@ -1,13 +1,21 @@ // 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. +#if NET45 using System.Collections.Generic; +using Microsoft.AspNet.Routing.Constraints; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.DependencyInjection.Fallback; +using Microsoft.Framework.OptionsModel; +using Moq; using Xunit; namespace Microsoft.AspNet.Routing.Template.Tests { public class TemplateMatcherTests { + private static IInlineConstraintResolver _inlineConstraintResolver = GetInlineConstraintResolver(); + [Fact] public void MatchSingleRoute() { @@ -784,13 +792,13 @@ namespace Microsoft.AspNet.Routing.Template.Tests private TemplateMatcher CreateMatcher(string template) { - return new TemplateMatcher(TemplateParser.Parse(template, new DefaultInlineConstraintResolver())); + return new TemplateMatcher(TemplateParser.Parse(template, _inlineConstraintResolver)); } private static void RunTest(string template, string path, IDictionary defaults, IDictionary expected) { // Arrange - var matcher = new TemplateMatcher(TemplateParser.Parse(template, new DefaultInlineConstraintResolver())); + var matcher = new TemplateMatcher(TemplateParser.Parse(template, _inlineConstraintResolver)); // Act var match = matcher.Match(path, defaults); @@ -810,5 +818,14 @@ namespace Microsoft.AspNet.Routing.Template.Tests } } } + + private static IInlineConstraintResolver GetInlineConstraintResolver() + { + var services = new ServiceCollection { OptionsServices.GetDefaultServices() }; + var serviceProvider = services.BuildServiceProvider(); + var accessor = serviceProvider.GetService>(); + return new DefaultInlineConstraintResolver(serviceProvider, accessor); + } } } +#endif \ No newline at end of file diff --git a/test/Microsoft.AspNet.Routing.Tests/Template/TemplateParserTests.cs b/test/Microsoft.AspNet.Routing.Tests/Template/TemplateParserTests.cs index 72ada89942..2a8bcd3bee 100644 --- a/test/Microsoft.AspNet.Routing.Tests/Template/TemplateParserTests.cs +++ b/test/Microsoft.AspNet.Routing.Tests/Template/TemplateParserTests.cs @@ -1,16 +1,21 @@ // 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. +#if NET45 using System; using System.Collections.Generic; using Microsoft.AspNet.Testing; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.DependencyInjection.Fallback; +using Microsoft.Framework.OptionsModel; +using Moq; using Xunit; namespace Microsoft.AspNet.Routing.Template.Tests { public class TemplateRouteParserTests { - private IInlineConstraintResolver _inlineConstraintResolver = new DefaultInlineConstraintResolver(); + private IInlineConstraintResolver _inlineConstraintResolver = GetInlineConstraintResolver(); [Fact] public void Parse_SingleLiteral() @@ -440,7 +445,15 @@ namespace Microsoft.AspNet.Routing.Template.Tests "A catch-all parameter cannot be marked optional." + Environment.NewLine + "Parameter name: routeTemplate"); } - + + private static IInlineConstraintResolver GetInlineConstraintResolver() + { + var services = new ServiceCollection { OptionsServices.GetDefaultServices() }; + var serviceProvider = services.BuildServiceProvider(); + var accessor = serviceProvider.GetService>(); + return new DefaultInlineConstraintResolver(serviceProvider, accessor); + } + private class TemplateEqualityComparer : IEqualityComparer