Remove obsolete APIs from routing (#7371)

This commit is contained in:
James Newton-King 2019-02-16 18:37:51 +13:00 committed by GitHub
parent 63a8b14619
commit c2d1ab925e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 10 additions and 295 deletions

View File

@ -21,17 +21,15 @@ namespace Microsoft.AspNetCore.Routing
/// <summary>
/// Initializes a new instance of the <see cref="DefaultInlineConstraintResolver"/> class.
/// </summary>
/// <param name="routeOptions">
/// Accessor for <see cref="RouteOptions"/> containing the constraints of interest.
/// </param>
[Obsolete("This constructor is obsolete. Use DefaultInlineConstraintResolver.ctor(IOptions<RouteOptions>, IServiceProvider) instead.")]
public DefaultInlineConstraintResolver(IOptions<RouteOptions> routeOptions)
{
_inlineConstraintMap = routeOptions.Value.ConstraintMap;
}
/// <param name="routeOptions">Accessor for <see cref="RouteOptions"/> containing the constraints of interest.</param>
/// <param name="serviceProvider">The <see cref="IServiceProvider"/> to get service arguments from.</param>
public DefaultInlineConstraintResolver(IOptions<RouteOptions> routeOptions, IServiceProvider serviceProvider)
{
if (routeOptions == null)
{
throw new ArgumentNullException(nameof(routeOptions));
}
if (serviceProvider == null)
{
throw new ArgumentNullException(nameof(serviceProvider));

View File

@ -1,26 +0,0 @@
// Copyright (c) .NET Foundation. 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.AspNetCore.Routing
{
/// <summary>
/// Represents metadata used during link generation to find
/// the associated endpoint using route values.
/// </summary>
[Obsolete("Route values are now specified on a RoutePattern.")]
public interface IRouteValuesAddressMetadata
{
/// <summary>
/// Gets the route name. Can be null.
/// </summary>
string RouteName { get; }
/// <summary>
/// Gets the required route values.
/// </summary>
IReadOnlyDictionary<string, object> RequiredValues { get; }
}
}

View File

@ -1,88 +0,0 @@
// Copyright (c) .NET Foundation. 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 System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
namespace Microsoft.AspNetCore.Routing
{
/// <summary>
/// Metadata used during link generation to find the associated endpoint using route values.
/// </summary>
[DebuggerDisplay("{DebuggerToString(),nq}")]
[Obsolete("Route values are now specified on a RoutePattern.")]
public sealed class RouteValuesAddressMetadata : IRouteValuesAddressMetadata
{
private static readonly IReadOnlyDictionary<string, object> EmptyRouteValues =
new ReadOnlyDictionary<string, object>(new Dictionary<string, object>());
/// <summary>
/// Creates a new instance of <see cref="RouteValuesAddressMetadata"/> with the provided route name.
/// </summary>
/// <param name="routeName">The route name. Can be null.</param>
public RouteValuesAddressMetadata(string routeName) : this(routeName, EmptyRouteValues)
{
}
/// <summary>
/// Creates a new instance of <see cref="RouteValuesAddressMetadata"/> with the provided required route values.
/// </summary>
/// <param name="requiredValues">The required route values.</param>
public RouteValuesAddressMetadata(IReadOnlyDictionary<string, object> requiredValues) : this(null, requiredValues)
{
}
/// <summary>
/// Creates a new instance of <see cref="RouteValuesAddressMetadata"/> with the provided route name and required route values.
/// </summary>
/// <param name="routeName">The route name. Can be null.</param>
/// <param name="requiredValues">The required route values.</param>
public RouteValuesAddressMetadata(string routeName, IReadOnlyDictionary<string, object> requiredValues)
{
if (requiredValues == null)
{
throw new ArgumentNullException(nameof(requiredValues));
}
RouteName = routeName;
RequiredValues = requiredValues;
}
/// <summary>
/// Gets the route name. Can be null.
/// </summary>
public string RouteName { get; }
/// <summary>
/// Gets the required route values.
/// </summary>
public IReadOnlyDictionary<string, object> RequiredValues { get; }
internal string DebuggerToString()
{
return $"Name: {RouteName} - Required values: {string.Join(", ", FormatValues(RequiredValues))}";
IEnumerable<string> FormatValues(IEnumerable<KeyValuePair<string, object>> values)
{
if (values == null)
{
return Array.Empty<string>();
}
return values.Select(
kvp =>
{
var value = "null";
if (kvp.Value != null)
{
value = "\"" + kvp.Value.ToString() + "\"";
}
return kvp.Key + " = " + value;
});
}
}
}
}

View File

@ -24,34 +24,6 @@ namespace Microsoft.AspNetCore.Routing.Tree
private readonly ObjectPool<UriBuildingContext> _objectPool;
private readonly IInlineConstraintResolver _constraintResolver;
/// <summary>
/// <para>
/// This constructor is obsolete and will be removed in a future version. The recommended
/// alternative is the overload that does not take a UrlEncoder.
/// </para>
/// <para>Initializes a new instance of <see cref="TreeRouteBuilder"/>.</para>
/// </summary>
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
/// <param name="urlEncoder">The <see cref="UrlEncoder"/>.</param>
/// <param name="objectPool">The <see cref="ObjectPool{UrlBuildingContext}"/>.</param>
/// <param name="constraintResolver">The <see cref="IInlineConstraintResolver"/>.</param>
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended " +
"alternative is the overload that does not take a UrlEncoder.")]
public TreeRouteBuilder(
ILoggerFactory loggerFactory,
UrlEncoder urlEncoder,
ObjectPool<UriBuildingContext> objectPool,
IInlineConstraintResolver constraintResolver)
: this(loggerFactory, objectPool, constraintResolver)
{
if (urlEncoder == null)
{
throw new ArgumentNullException(nameof(urlEncoder));
}
_urlEncoder = urlEncoder;
}
/// <summary>
/// Initializes a new instance of <see cref="TreeRouteBuilder"/>.
/// </summary>

View File

@ -325,33 +325,12 @@ namespace Microsoft.AspNetCore.Routing.Tests
ex.Message);
}
[Fact]
public void ResolveConstraint_HasArguments_NoServiceProvider()
{
// Arrange
var routeOptions = new RouteOptions();
var constraintResolver = GetInlineConstraintResolver(routeOptions, hasServiceProvider: false);
// Act
var constraint = constraintResolver.ResolveConstraint("regex(ab,1)");
// Assert
Assert.IsType<RegexInlineRouteConstraint>(constraint);
}
private IInlineConstraintResolver GetInlineConstraintResolver(RouteOptions routeOptions, bool hasServiceProvider = true)
private IInlineConstraintResolver GetInlineConstraintResolver(RouteOptions routeOptions)
{
var optionsAccessor = new Mock<IOptions<RouteOptions>>();
optionsAccessor.SetupGet(o => o.Value).Returns(routeOptions);
if (hasServiceProvider)
{
return new DefaultInlineConstraintResolver(optionsAccessor.Object, new TestServiceProvider());
}
#pragma warning disable CS0618 // Type or member is obsolete
return new DefaultInlineConstraintResolver(optionsAccessor.Object);
#pragma warning restore CS0618 // Type or member is obsolete
return new DefaultInlineConstraintResolver(optionsAccessor.Object, new TestServiceProvider());
}
private class MultiConstructorRouteConstraint : IRouteConstraint

View File

@ -1,37 +0,0 @@
// Copyright (c) .NET Foundation. 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 System.Text;
using Xunit;
namespace Microsoft.AspNetCore.Routing
{
public class RouteValuesAddressMetadataTests
{
[Fact]
public void DebuggerToString_NoNameAndRequiredValues_ReturnsString()
{
#pragma warning disable CS0618 // Type or member is obsolete
var metadata = new RouteValuesAddressMetadata(null, new Dictionary<string, object>());
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Equal("Name: - Required values: ", metadata.DebuggerToString());
}
[Fact]
public void DebuggerToString_HasNameAndRequiredValues_ReturnsString()
{
#pragma warning disable CS0618 // Type or member is obsolete
var metadata = new RouteValuesAddressMetadata("Name!", new Dictionary<string, object>
{
["requiredValue1"] = "One",
["requiredValue2"] = 2,
});
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Equal("Name: Name! - Required values: requiredValue1 = \"One\", requiredValue2 = \"2\"", metadata.DebuggerToString());
}
}
}

View File

@ -26,70 +26,6 @@ namespace Microsoft.AspNetCore.Routing.Tree
private static ObjectPool<UriBuildingContext> Pool = new DefaultObjectPoolProvider().Create(
new UriBuilderContextPooledObjectPolicy());
[Fact]
public async Task TreeRouter_RouteAsync_MatchesCatchAllRoutesWithDefaults_UsingObsoleteConstructo()
{
// Arrange
var routes = new[] {
"{parameter1=1}/{parameter2=2}/{parameter3=3}/{*parameter4=4}",
};
var url = "/a/b/c";
var routeValues = new[] { "a", "b", "c", "4" };
var expectedRouteGroup = CreateRouteGroup(0, "{parameter1=1}/{parameter2=2}/{parameter3=3}/{*parameter4=4}");
var routeValueKeys = new[] { "parameter1", "parameter2", "parameter3", "parameter4" };
var expectedRouteValues = new RouteValueDictionary();
for (var i = 0; i < routeValueKeys.Length; i++)
{
expectedRouteValues.Add(routeValueKeys[i], routeValues[i]);
}
var builder = CreateBuilderUsingObsoleteConstructor();
// We setup the route entries in reverse order of precedence to ensure that when we
// try to route the request, the route with a higher precedence gets tried first.
foreach (var template in routes.Reverse())
{
MapInboundEntry(builder, template);
}
var route = builder.Build();
var context = CreateRouteContext(url);
// Act
await route.RouteAsync(context);
// Assert
Assert.Equal(expectedRouteGroup, context.RouteData.Values["test_route_group"]);
foreach (var entry in expectedRouteValues)
{
var data = Assert.Single(context.RouteData.Values, v => v.Key == entry.Key);
Assert.Equal(entry.Value, data.Value);
}
}
[Fact]
public async Task TreeRouter_RouteAsync_DoesNotMatchRoutesWithIntermediateDefaultRouteValues_UsingObsoleteConstructor()
{
// Arrange
var url = "/a/b";
var builder = CreateBuilderUsingObsoleteConstructor();
MapInboundEntry(builder, "a/b/{parameter3=3}/d");
var route = builder.Build();
var context = CreateRouteContext(url);
// Act
await route.RouteAsync(context);
// Assert
Assert.Null(context.Handler);
}
[Theory]
[InlineData("template/5", "template/{parameter:int}")]
[InlineData("template/5", "template/{parameter}")]
@ -2151,23 +2087,6 @@ namespace Microsoft.AspNetCore.Routing.Tree
return builder;
}
private static TreeRouteBuilder CreateBuilderUsingObsoleteConstructor()
{
var objectPoolProvider = new DefaultObjectPoolProvider();
var objectPolicy = new UriBuilderContextPooledObjectPolicy();
var objectPool = objectPoolProvider.Create<UriBuildingContext>(objectPolicy);
var constraintResolver = CreateConstraintResolver();
#pragma warning disable CS0618 // Type or member is obsolete
var builder = new TreeRouteBuilder(
NullLoggerFactory.Instance,
UrlEncoder.Default,
objectPool,
constraintResolver);
#pragma warning restore CS0618 // Type or member is obsolete
return builder;
}
private static TreeRouter CreateTreeRouter(
string firstTemplate,
string secondTemplate)

View File

@ -174,9 +174,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
.SetupGet(o => o.Value)
.Returns(new RouteOptions());
#pragma warning disable CS0618 // Type or member is obsolete
var inlineConstraintResolver = new DefaultInlineConstraintResolver(routeOptions.Object);
#pragma warning restore CS0618 // Type or member is obsolete
var inlineConstraintResolver = new DefaultInlineConstraintResolver(routeOptions.Object, Mock.Of<IServiceProvider>());
var services = new ServiceCollection()
.AddSingleton<IInlineConstraintResolver>(inlineConstraintResolver);