Check dispatcher services registered (#610)
This commit is contained in:
parent
5e1f99faaf
commit
73e4d55d7b
|
|
@ -1,7 +1,10 @@
|
|||
// 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 Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
|
|
@ -9,12 +12,29 @@ namespace Microsoft.AspNetCore.Builder
|
|||
{
|
||||
public static IApplicationBuilder UseDispatcher(this IApplicationBuilder builder)
|
||||
{
|
||||
VerifyDispatcherIsRegistered(builder);
|
||||
|
||||
return builder.UseMiddleware<DispatcherMiddleware>();
|
||||
}
|
||||
|
||||
public static IApplicationBuilder UseEndpoint(this IApplicationBuilder builder)
|
||||
{
|
||||
VerifyDispatcherIsRegistered(builder);
|
||||
|
||||
return builder.UseMiddleware<EndpointMiddleware>();
|
||||
}
|
||||
|
||||
private static void VerifyDispatcherIsRegistered(IApplicationBuilder app)
|
||||
{
|
||||
// Verify if AddDispatcher was done before calling UseDispatcher/UseEndpoint
|
||||
// We use the DispatcherMarkerService to make sure if all the services were added.
|
||||
if (app.ApplicationServices.GetService(typeof(DispatcherMarkerService)) == null)
|
||||
{
|
||||
throw new InvalidOperationException(Resources.FormatUnableToFindServices(
|
||||
nameof(IServiceCollection),
|
||||
nameof(DispatcherServiceCollectionExtensions.AddDispatcher),
|
||||
"ConfigureServices(...)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Reflection;
|
|||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.EndpointConstraints;
|
||||
using Microsoft.AspNetCore.Routing.EndpointFinders;
|
||||
using Microsoft.AspNetCore.Routing.Internal;
|
||||
using Microsoft.AspNetCore.Routing.Matchers;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
|
@ -34,6 +35,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
//
|
||||
// Default matcher implementation
|
||||
//
|
||||
services.TryAddSingleton<MatchProcessorFactory, DefaultMatchProcessorFactory>();
|
||||
services.TryAddSingleton<MatcherFactory, TreeMatcherFactory>();
|
||||
|
||||
// Link generation related services
|
||||
|
|
@ -50,6 +52,8 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.TryAddEnumerable(
|
||||
ServiceDescriptor.Transient<IEndpointConstraintProvider, DefaultEndpointConstraintProvider>());
|
||||
|
||||
services.TryAddSingleton(typeof(DispatcherMarkerService));
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
throw new ArgumentNullException(nameof(services));
|
||||
}
|
||||
|
||||
services.TryAddSingleton<MatchProcessorFactory, DefaultMatchProcessorFactory>();
|
||||
services.TryAddTransient<IInlineConstraintResolver, DefaultInlineConstraintResolver>();
|
||||
services.TryAddSingleton<ObjectPool<UriBuildingContext>>(s =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
// 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 Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// A marker class used to determine if all the dispatcher services were added
|
||||
/// to the <see cref="IServiceCollection"/> before dispatcher is configured.
|
||||
/// </summary>
|
||||
internal class DispatcherMarkerService
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Routing.Internal
|
|||
/// A marker class used to determine if all the routing services were added
|
||||
/// to the <see cref="IServiceCollection"/> before routing is configured.
|
||||
/// </summary>
|
||||
public class RoutingMarkerService
|
||||
internal class RoutingMarkerService
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
// 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.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder.Internal;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public class DispatcherApplicationBuilderExtensions
|
||||
{
|
||||
[Fact]
|
||||
public void UseDispatcher_ServicesNotRegistered_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var app = new ApplicationBuilder(Mock.Of<IServiceProvider>());
|
||||
|
||||
// Act
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => app.UseDispatcher());
|
||||
|
||||
// Assert
|
||||
Assert.Equal(
|
||||
"Unable to find the required services. " +
|
||||
"Please add all the required services by calling 'IServiceCollection.AddDispatcher' " +
|
||||
"inside the call to 'ConfigureServices(...)' in the application startup code.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UseEndpoint_ServicesNotRegistered_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var app = new ApplicationBuilder(Mock.Of<IServiceProvider>());
|
||||
|
||||
// Act
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => app.UseEndpoint());
|
||||
|
||||
// Assert
|
||||
Assert.Equal(
|
||||
"Unable to find the required services. " +
|
||||
"Please add all the required services by calling 'IServiceCollection.AddDispatcher' " +
|
||||
"inside the call to 'ConfigureServices(...)' in the application startup code.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UseDispatcher_ServicesRegistered_SetsFeature()
|
||||
{
|
||||
// Arrange
|
||||
var services = CreateServices();
|
||||
|
||||
var app = new ApplicationBuilder(services);
|
||||
|
||||
app.UseDispatcher();
|
||||
|
||||
var appFunc = app.Build();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
|
||||
// Act
|
||||
await appFunc(httpContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(httpContext.Features.Get<IEndpointFeature>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UseEndpoint_ServicesRegistered_SetsFeature()
|
||||
{
|
||||
// Arrange
|
||||
var services = CreateServices();
|
||||
|
||||
var app = new ApplicationBuilder(services);
|
||||
|
||||
app.UseDispatcher();
|
||||
app.UseEndpoint();
|
||||
|
||||
var appFunc = app.Build();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
|
||||
// Act
|
||||
await appFunc(httpContext);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(httpContext.Features.Get<IEndpointFeature>());
|
||||
}
|
||||
|
||||
private IServiceProvider CreateServices()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.AddLogging();
|
||||
services.AddOptions();
|
||||
services.AddDispatcher();
|
||||
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue