Skip to content
This repository was archived by the owner on Nov 27, 2018. It is now read-only.

Commit a499d4a

Browse files
committed
Routing DI Changes II : Adding services for routing.
1 parent 28b89c8 commit a499d4a

16 files changed

+284
-77
lines changed
Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Text.RegularExpressions;
34
using Microsoft.AspNet.Builder;
5+
using Microsoft.AspNet.Http;
46
using Microsoft.AspNet.Routing;
57
using Microsoft.AspNet.Routing.Constraints;
68
using Microsoft.Framework.DependencyInjection;
9+
using Microsoft.Framework.OptionsModel;
710

811
namespace RoutingSample.Web
912
{
1013
public class Startup
1114
{
1215
public void Configure(IBuilder builder)
1316
{
14-
var collectionBuilder = new RouteBuilder();
17+
builder.UseServices(services =>
18+
{
19+
services.Add(RoutingServices.GetDefaultServices());
20+
});
1521

1622
var endpoint1 = new DelegateRouteEndpoint(async (context) =>
1723
await context
@@ -20,37 +26,38 @@ await context
2026
.WriteAsync(
2127
"match1, route values -" + context.RouteData.Values.Print()));
2228

23-
var endpoint2 = new DelegateRouteEndpoint(async (context) =>
29+
var endpoint2 = new DelegateRouteEndpoint(async (context) =>
2430
await context
2531
.HttpContext
2632
.Response
2733
.WriteAsync("Hello, World!"));
2834

29-
collectionBuilder.DefaultHandler = endpoint1;
30-
collectionBuilder.ServiceProvider = builder.ApplicationServices;
31-
32-
collectionBuilder.AddPrefixRoute("api/store");
33-
34-
collectionBuilder.MapRoute("defaultRoute",
35-
"api/constraint/{controller}",
36-
null,
37-
new { controller = "my.*" });
38-
collectionBuilder.MapRoute("regexStringRoute",
39-
"api/rconstraint/{controller}",
40-
new { foo = "Bar" },
41-
new { controller = new RegexConstraint("^(my.*)$") });
42-
collectionBuilder.MapRoute("regexRoute",
43-
"api/r2constraint/{controller}",
44-
new { foo = "Bar2" },
45-
new { controller = new RegexConstraint(new Regex("^(my.*)$")) });
46-
47-
collectionBuilder.MapRoute("parameterConstraintRoute",
48-
"api/{controller}/{*extra}",
49-
new { controller = "Store" });
50-
51-
collectionBuilder.AddPrefixRoute("hello/world", endpoint2);
52-
collectionBuilder.AddPrefixRoute("", endpoint2);
53-
builder.UseRouter(collectionBuilder.Build());
35+
var routeBuilder = new RouteBuilder();
36+
routeBuilder.DefaultHandler = endpoint1;
37+
routeBuilder.ServiceProvider = builder.ApplicationServices;
38+
39+
routeBuilder.AddPrefixRoute("api/store");
40+
41+
routeBuilder.MapRoute("defaultRoute",
42+
"api/constraint/{controller}",
43+
null,
44+
new { controller = "my.*" });
45+
routeBuilder.MapRoute("regexStringRoute",
46+
"api/rconstraint/{controller}",
47+
new { foo = "Bar" },
48+
new { controller = new RegexConstraint("^(my.*)$") });
49+
routeBuilder.MapRoute("regexRoute",
50+
"api/r2constraint/{controller}",
51+
new { foo = "Bar2" },
52+
new { controller = new RegexConstraint(new Regex("^(my.*)$")) });
53+
54+
routeBuilder.MapRoute("parameterConstraintRoute",
55+
"api/{controller}/{*extra}",
56+
new { controller = "Store" });
57+
58+
routeBuilder.AddPrefixRoute("hello/world", endpoint2);
59+
routeBuilder.AddPrefixRoute("", endpoint2);
60+
builder.UseRouter(routeBuilder.Build());
5461
}
5562
}
5663
}

samples/RoutingSample.Web/project.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
"version": "0.1-alpha-*",
33
"dependencies": {
44
"Helios": "0.1-alpha-*",
5-
"Microsoft.AspNet.Routing" : ""
5+
"Microsoft.AspNet.Routing" : "",
6+
"Microsoft.AspNet.RequestContainer": "0.1-alpha-*",
7+
"Microsoft.Framework.OptionsModel": "0.1-alpha-*"
68
},
79
"configurations": {
810
"net45": { },

src/Microsoft.AspNet.Routing/DefaultInlineConstraintResolver.cs

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
using System.Globalization;
77
using System.Linq;
88
using System.Reflection;
9-
using Microsoft.AspNet.Routing.Constraints;
9+
using Microsoft.Framework.DependencyInjection;
10+
using Microsoft.Framework.OptionsModel;
1011

1112
namespace Microsoft.AspNet.Routing
1213
{
@@ -17,26 +18,14 @@ namespace Microsoft.AspNet.Routing
1718
/// </summary>
1819
public class DefaultInlineConstraintResolver : IInlineConstraintResolver
1920
{
20-
private readonly IDictionary<string, Type> _inlineConstraintMap = GetDefaultConstraintMap();
21+
private readonly IDictionary<string, Type> _inlineConstraintMap;
22+
private readonly IServiceProvider _serviceProvider;
2123

22-
/// <summary>
23-
/// Gets the mutable dictionary that maps constraint keys to a particular constraint type.
24-
/// </summary>
25-
public IDictionary<string, Type> ConstraintMap
24+
public DefaultInlineConstraintResolver(IServiceProvider serviceProvider,
25+
IOptionsAccessor<RouteOptions> routeOptions)
2626
{
27-
get
28-
{
29-
return _inlineConstraintMap;
30-
}
31-
}
32-
33-
private static IDictionary<string, Type> GetDefaultConstraintMap()
34-
{
35-
return new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase)
36-
{
37-
// Type-specific constraints
38-
{ "int", typeof(IntRouteConstraint) },
39-
};
27+
_serviceProvider = serviceProvider;
28+
_inlineConstraintMap = routeOptions.Options.ConstraintMap;
4029
}
4130

4231
/// <inheritdoc />

src/Microsoft.AspNet.Routing/Microsoft.AspNet.Routing.kproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
</PropertyGroup>
1919
<ItemGroup>
2020
<Content Include="project.json" />
21-
<Content Include="Resources.resx" />
21+
<Content Include="Resources.resx">
22+
<SubType>Designer</SubType>
23+
</Content>
2224
</ItemGroup>
2325
<ItemGroup>
2426
<Compile Include="BuilderExtensions.cs" />
@@ -30,6 +32,7 @@
3032
<Compile Include="INamedRouter.cs" />
3133
<Compile Include="InlineRouteParameterParser.cs" />
3234
<Compile Include="IRouteBuilder.cs" />
35+
<Compile Include="RouteOptions.cs" />
3336
<Compile Include="IRouteCollection.cs" />
3437
<Compile Include="IRouteConstraint.cs" />
3538
<Compile Include="IRouter.cs" />
@@ -43,6 +46,7 @@
4346
<Compile Include="RouteContext.cs" />
4447
<Compile Include="RouteData.cs" />
4548
<Compile Include="RouteDirection.cs" />
49+
<Compile Include="RouterServices.cs" />
4650
<Compile Include="RouterMiddleware.cs" />
4751
<Compile Include="RouteValueDictionary.cs" />
4852
<Compile Include="Template\Template.cs" />

src/Microsoft.AspNet.Routing/Properties/Resources.Designer.cs

Lines changed: 18 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Microsoft.AspNet.Routing/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@
117117
<resheader name="writer">
118118
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119119
</resheader>
120+
<data name="PropertyOfTypeCannotBeNull" xml:space="preserve">
121+
<value>The '{0}' property of '{1}' must not be null.</value>
122+
</data>
120123
<data name="NamedRoutes_AmbiguousRoutesFound" xml:space="preserve">
121124
<value>The supplied route name '{0}' is ambiguous and matched more than one route.</value>
122125
</data>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using Microsoft.AspNet.Routing.Constraints;
7+
8+
namespace Microsoft.AspNet.Routing
9+
{
10+
public class RouteOptions
11+
{
12+
private IDictionary<string, Type> _constraintTypeMap = GetDefaultConstraintMap();
13+
14+
public IDictionary<string, Type> ConstraintMap
15+
{
16+
get
17+
{
18+
return _constraintTypeMap;
19+
}
20+
set
21+
{
22+
if(value == null)
23+
{
24+
throw new ArgumentNullException("value",
25+
Resources.FormatPropertyOfTypeCannotBeNull(
26+
"ConstraintMap", typeof(RouteOptions)));
27+
}
28+
29+
_constraintTypeMap = value;
30+
}
31+
}
32+
33+
private static IDictionary<string, Type> GetDefaultConstraintMap()
34+
{
35+
return new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase)
36+
{
37+
// Type-specific constraints
38+
{ "int", typeof(IntRouteConstraint) },
39+
};
40+
}
41+
}
42+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Collections.Generic;
5+
using System.Threading.Tasks;
6+
using Microsoft.AspNet.Http;
7+
using Microsoft.AspNet.Routing;
8+
using Microsoft.Framework.ConfigurationModel;
9+
using Microsoft.Framework.DependencyInjection;
10+
using Microsoft.Framework.DependencyInjection.NestedProviders;
11+
12+
namespace Microsoft.AspNet.Routing
13+
{
14+
public class RoutingServices
15+
{
16+
public static IEnumerable<IServiceDescriptor> GetDefaultServices()
17+
{
18+
return GetDefaultServices(new Configuration());
19+
}
20+
21+
public static IEnumerable<IServiceDescriptor> GetDefaultServices(IConfiguration configuration)
22+
{
23+
var describe = new ServiceDescriber(configuration);
24+
25+
yield return describe.Transient<IInlineConstraintResolver, DefaultInlineConstraintResolver>();
26+
}
27+
}
28+
}

src/Microsoft.AspNet.Routing/project.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
},
66
"dependencies": {
77
"Microsoft.AspNet.Http": "0.1-alpha-*",
8-
"Microsoft.Framework.DependencyInjection" : "0.1-alpha-*"
8+
"Microsoft.Framework.DependencyInjection" : "0.1-alpha-*",
9+
"Microsoft.AspNet.RequestContainer": "0.1-alpha-*",
10+
"Microsoft.Framework.OptionsModel": "0.1-alpha-*"
911
},
1012
"configurations": {
1113
"net45": {},

test/Microsoft.AspNet.Routing.Tests/DefaultInlineConstraintResolverTest.cs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
#if NET45
45
using System;
56
using System.Collections.Generic;
67
using Microsoft.AspNet.Http;
78
using Microsoft.AspNet.Routing.Constraints;
9+
using Microsoft.Framework.DependencyInjection;
10+
using Microsoft.Framework.OptionsModel;
11+
using Moq;
812
using Xunit;
913

1014
namespace Microsoft.AspNet.Routing.Tests
@@ -14,8 +18,12 @@ public class DefaultInlineConstraintResolverTest
1418
[Fact]
1519
public void ResolveConstraint_IntConstraint_ResolvesCorrectly()
1620
{
17-
// Arrange & Act
18-
var constraint = new DefaultInlineConstraintResolver().ResolveConstraint("int");
21+
// Arrange
22+
var routeOptions = new RouteOptions();
23+
var constraintResolver = GetInlineConstraintResolver(routeOptions);
24+
25+
// Act
26+
var constraint = constraintResolver.ResolveConstraint("int");
1927

2028
// Assert
2129
Assert.IsType<IntRouteConstraint>(constraint);
@@ -24,9 +32,13 @@ public void ResolveConstraint_IntConstraint_ResolvesCorrectly()
2432
[Fact]
2533
public void ResolveConstraint_IntConstraintWithArgument_Throws()
2634
{
35+
// Arrange
36+
var routeOptions = new RouteOptions();
37+
var constraintResolver = GetInlineConstraintResolver(routeOptions);
38+
2739
// Act & Assert
2840
var ex = Assert.Throws<InvalidOperationException>(
29-
() => new DefaultInlineConstraintResolver().ResolveConstraint("int(5)"));
41+
() => constraintResolver.ResolveConstraint("int(5)"));
3042
Assert.Equal("Could not find a constructor for constraint type 'IntRouteConstraint'"+
3143
" with the following number of parameters: 1.",
3244
ex.Message);
@@ -36,8 +48,9 @@ public void ResolveConstraint_IntConstraintWithArgument_Throws()
3648
public void ResolveConstraint_SupportsCustomConstraints()
3749
{
3850
// Arrange
39-
var resolver = new DefaultInlineConstraintResolver();
40-
resolver.ConstraintMap.Add("custom", typeof(CustomRouteConstraint));
51+
var routeOptions = new RouteOptions();
52+
routeOptions.ConstraintMap.Add("custom", typeof(CustomRouteConstraint));
53+
var resolver = GetInlineConstraintResolver(routeOptions);
4154

4255
// Act
4356
var constraint = resolver.ResolveConstraint("custom(argument)");
@@ -50,8 +63,9 @@ public void ResolveConstraint_SupportsCustomConstraints()
5063
public void ResolveConstraint_CustomConstraintThatDoesNotImplementIRouteConstraint_Throws()
5164
{
5265
// Arrange
53-
var resolver = new DefaultInlineConstraintResolver();
54-
resolver.ConstraintMap.Add("custom", typeof(string));
66+
var routeOptions = new RouteOptions();
67+
routeOptions.ConstraintMap.Add("custom", typeof(string));
68+
var resolver = GetInlineConstraintResolver(routeOptions);
5569

5670
// Act & Assert
5771
var ex = Assert.Throws<InvalidOperationException>(() => resolver.ResolveConstraint("custom"));
@@ -60,6 +74,16 @@ public void ResolveConstraint_CustomConstraintThatDoesNotImplementIRouteConstrai
6074
ex.Message);
6175
}
6276

77+
private IInlineConstraintResolver GetInlineConstraintResolver(RouteOptions routeOptions)
78+
{
79+
var optionsAccessor = new Mock<IOptionsAccessor<RouteOptions>>();
80+
optionsAccessor.SetupGet(o => o.Options).Returns(routeOptions);
81+
var serviceProvider = new Mock<IServiceProvider>();
82+
serviceProvider.Setup(o => o.GetService(It.Is<Type>(type => type == typeof(ITypeActivator))))
83+
.Returns(new TypeActivator());
84+
return new DefaultInlineConstraintResolver(serviceProvider.Object, optionsAccessor.Object);
85+
}
86+
6387
private class CustomRouteConstraint : IRouteConstraint
6488
{
6589
public CustomRouteConstraint(string pattern)
@@ -79,3 +103,4 @@ public bool Match(HttpContext httpContext,
79103
}
80104
}
81105
}
106+
#endif

0 commit comments

Comments
 (0)