From 069fd0f35008e00a2bf77c65013cc3973d0c8d65 Mon Sep 17 00:00:00 2001 From: James Restall <6826786+jrestall@users.noreply.github.com> Date: Sat, 14 Apr 2018 16:37:11 +1200 Subject: [PATCH] Adding IStartupFilter support The middleware pipeline for a tenant can now be configured using IStartupFilter, this allows libraries that use this interface as part of their initialisation to work e.g. Microsoft.AspNetCore.Mvc.Versioning. --- .../ModularTenantRouterMiddleware.cs | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Modules/ModularTenantRouterMiddleware.cs b/src/OrchardCore/OrchardCore.Modules/ModularTenantRouterMiddleware.cs index 534a4aaa691..936acf6ab13 100644 --- a/src/OrchardCore/OrchardCore.Modules/ModularTenantRouterMiddleware.cs +++ b/src/OrchardCore/OrchardCore.Modules/ModularTenantRouterMiddleware.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder.Internal; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -37,7 +38,6 @@ public async Task Invoke(HttpContext httpContext) _logger.LogInformation("Begin Routing Request"); } - var shellSettings = httpContext.Features.Get(); // Define a PathBase for the current request that is the RequestUrlPrefix. @@ -85,15 +85,32 @@ public async Task Invoke(HttpContext httpContext) // Build the middleware pipeline for the current tenant public RequestDelegate BuildTenantPipeline(ShellSettings shellSettings, IServiceProvider serviceProvider) { - var startups = serviceProvider.GetServices(); + var appBuilder = new ApplicationBuilder(serviceProvider); + + // Create a nested pipeline to configure the tenant middleware pipeline + var startupFilters = serviceProvider.GetService>(); + Action configure = ConfigureTenantPipeline; + foreach (var filter in startupFilters.Reverse()) + { + configure = filter.Configure(configure); + } + + configure(appBuilder); + + var pipeline = appBuilder.Build(); + + return pipeline; + } + + private void ConfigureTenantPipeline(IApplicationBuilder builder) + { + var startups = builder.ApplicationServices.GetServices(); // IStartup instances are ordered by module dependency with an Order of 0 by default. // OrderBy performs a stable sort so order is preserved among equal Order values. startups = startups.OrderBy(s => s.Order); - var tenantRouteBuilder = serviceProvider.GetService(); - - var appBuilder = new ApplicationBuilder(serviceProvider); + var tenantRouteBuilder = builder.ApplicationServices.GetService(); var routeBuilder = tenantRouteBuilder.Build(); // In the case of several tenants, they will all be checked by ShellSettings. To optimize @@ -102,18 +119,14 @@ public RequestDelegate BuildTenantPipeline(ShellSettings shellSettings, IService // And the ShellSettings test in TenantRoute would also be useless. foreach (var startup in startups) { - startup.Configure(appBuilder, routeBuilder, serviceProvider); + startup.Configure(builder, routeBuilder, builder.ApplicationServices); } tenantRouteBuilder.Configure(routeBuilder); var router = routeBuilder.Build(); - appBuilder.UseRouter(router); - - var pipeline = appBuilder.Build(); - - return pipeline; + builder.UseRouter(router); } } }