diff --git a/aspnetcore/fundamentals/middleware/extensibility.md b/aspnetcore/fundamentals/middleware/extensibility.md index 19d08f4e99..7dbcc7bf31 100644 --- a/aspnetcore/fundamentals/middleware/extensibility.md +++ b/aspnetcore/fundamentals/middleware/extensibility.md @@ -11,11 +11,11 @@ uid: fundamentals/middleware/extensibility --- # Factory-based middleware activation in ASP.NET Core -:::moniker range=">= aspnetcore-3.0" +:::moniker range=">= aspnetcore-6.0" / is an extensibility point for [middleware](xref:fundamentals/middleware/index) activation. - extension methods check if a middleware's registered type implements . If it does, the instance registered in the container is used to resolve the implementation instead of using the convention-based middleware activation logic. The middleware is registered as a [scoped or transient service](xref:fundamentals/dependency-injection#service-lifetimes) in the app's service container. + extension methods check if a middleware's registered type implements . If it does, the instance registered in the container is used to resolve the implementation instead of using the convention-based middleware activation logic. The middleware is registered as a [scoped or transient service](xref:fundamentals/dependency-injection#service-lifetimes) in the app's service container. Benefits: @@ -28,21 +28,21 @@ Benefits: ## IMiddleware - defines middleware for the app's request pipeline. The [InvokeAsync(HttpContext, RequestDelegate)](xref:Microsoft.AspNetCore.Http.IMiddleware.InvokeAsync*) method handles requests and returns a that represents the execution of the middleware. + defines middleware for the app's request pipeline. The [InvokeAsync(HttpContext, RequestDelegate)](xref:Microsoft.AspNetCore.Http.IMiddleware.InvokeAsync%2A) method handles requests and returns a that represents the execution of the middleware. Middleware activated by convention: -[!code-csharp[](extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs?name=snippet1)] +:::code language="csharp" source="extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs" id="snippet1"::: Middleware activated by : -[!code-csharp[](extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs?name=snippet1)] +:::code language="csharp" source="extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs" id="snippet1"::: -Extensions are created for the middlewares: +Extensions are created for the middleware: -[!code-csharp[](extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs?name=snippet1)] +:::code language="csharp" source="extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs" id="snippet1"::: -It isn't possible to pass objects to the factory-activated middleware with : +It isn't possible to pass objects to the factory-activated middleware with : ```csharp public static IApplicationBuilder UseFactoryActivatedMiddleware( @@ -55,11 +55,11 @@ public static IApplicationBuilder UseFactoryActivatedMiddleware( The factory-activated middleware is added to the built-in container in `Startup.ConfigureServices`: -[!code-csharp[](extensibility/samples/3.x/MiddlewareExtensibilitySample/Startup.cs?name=snippet1&highlight=6)] +:::code language="csharp" source="extensibility/samples/3.x/MiddlewareExtensibilitySample/Startup.cs" id="snippet1" highlight="6"::: -Both middlewares are registered in the request processing pipeline in `Startup.Configure`: +Both middleware are registered in the request processing pipeline in `Startup.Configure`: -[!code-csharp[](extensibility/samples/3.x/MiddlewareExtensibilitySample/Startup.cs?name=snippet2&highlight=12-13)] +:::code language="csharp" source="extensibility/samples/3.x/MiddlewareExtensibilitySample/Startup.cs" id="snippet2" highlight="12-13"::: ## IMiddlewareFactory @@ -67,13 +67,82 @@ Both middlewares are registered in the request processing pipeline in `Startup.C The default implementation, , is found in the [Microsoft.AspNetCore.Http](https://www.nuget.org/packages/Microsoft.AspNetCore.Http/) package. +## Additional resources + +* +* + +:::moniker-end + + +:::moniker range=">= aspnetcore-3.0 < aspnetcore-6.0" + +/ is an extensibility point for [middleware](xref:fundamentals/middleware/index) activation. + + extension methods check if a middleware's registered type implements . If it does, the instance registered in the container is used to resolve the implementation instead of using the convention-based middleware activation logic. The middleware is registered as a [scoped or transient service](xref:fundamentals/dependency-injection#service-lifetimes) in the app's service container. + +Benefits: + +* Activation per client request (injection of scoped services) +* Strong typing of middleware + + is activated per client request (connection), so scoped services can be injected into the middleware's constructor. + +[View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/middleware/extensibility/samples) ([how to download](xref:index#how-to-download-a-sample)) + +## IMiddleware + + defines middleware for the app's request pipeline. The [InvokeAsync(HttpContext, RequestDelegate)](xref:Microsoft.AspNetCore.Http.IMiddleware.InvokeAsync%2A) method handles requests and returns a that represents the execution of the middleware. + +Middleware activated by convention: + +:::code language="csharp" source="extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs" id="snippet1"::: + +Middleware activated by : + +:::code language="csharp" source="extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs" id="snippet1"::: + +Extensions are created for the middleware: + +:::code language="csharp" source="extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs" id="snippet1"::: + +It isn't possible to pass objects to the factory-activated middleware with : + +```csharp +public static IApplicationBuilder UseFactoryActivatedMiddleware( + this IApplicationBuilder builder, bool option) +{ + // Passing 'option' as an argument throws a NotSupportedException at runtime. + return builder.UseMiddleware(option); +} +``` + +The factory-activated middleware is added to the built-in container in `Startup.ConfigureServices`: + +:::code language="csharp" source="extensibility/samples/3.x/MiddlewareExtensibilitySample/Startup.cs" id="snippet1" highlight="6"::: + +Both middleware are registered in the request processing pipeline in `Startup.Configure`: + +:::code language="csharp" source="extensibility/samples/3.x/MiddlewareExtensibilitySample/Startup.cs" id="snippet2" highlight="12-13"::: + +## IMiddlewareFactory + + provides methods to create middleware. The middleware factory implementation is registered in the container as a scoped service. + +The default implementation, , is found in the [Microsoft.AspNetCore.Http](https://www.nuget.org/packages/Microsoft.AspNetCore.Http/) package. + +## Additional resources + +* +* + :::moniker-end :::moniker range="< aspnetcore-3.0" / is an extensibility point for [middleware](xref:fundamentals/middleware/index) activation. - extension methods check if a middleware's registered type implements . If it does, the instance registered in the container is used to resolve the implementation instead of using the convention-based middleware activation logic. The middleware is registered as a [scoped or transient service](xref:fundamentals/dependency-injection#service-lifetimes) in the app's service container. + extension methods check if a middleware's registered type implements . If it does, the instance registered in the container is used to resolve the implementation instead of using the convention-based middleware activation logic. The middleware is registered as a [scoped or transient service](xref:fundamentals/dependency-injection#service-lifetimes) in the app's service container. Benefits: @@ -86,21 +155,21 @@ Benefits: ## IMiddleware - defines middleware for the app's request pipeline. The [InvokeAsync(HttpContext, RequestDelegate)](xref:Microsoft.AspNetCore.Http.IMiddleware.InvokeAsync*) method handles requests and returns a that represents the execution of the middleware. + defines middleware for the app's request pipeline. The [InvokeAsync(HttpContext, RequestDelegate)](xref:Microsoft.AspNetCore.Http.IMiddleware.InvokeAsync%2A) method handles requests and returns a that represents the execution of the middleware. Middleware activated by convention: -[!code-csharp[](extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs?name=snippet1)] +:::code language="csharp" source="extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs" id="snippet1"::: Middleware activated by : -[!code-csharp[](extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs?name=snippet1)] +:::code language="csharp" source="extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs" id="snippet1"::: -Extensions are created for the middlewares: +Extensions are created for the middleware: -[!code-csharp[](extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs?name=snippet1)] +:::code language="csharp" source="extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs" id="snippet1"::: -It isn't possible to pass objects to the factory-activated middleware with : +It isn't possible to pass objects to the factory-activated middleware with : ```csharp public static IApplicationBuilder UseFactoryActivatedMiddleware( @@ -113,11 +182,11 @@ public static IApplicationBuilder UseFactoryActivatedMiddleware( The factory-activated middleware is added to the built-in container in `Startup.ConfigureServices`: -[!code-csharp[](extensibility/samples/2.x/MiddlewareExtensibilitySample/Startup.cs?name=snippet1&highlight=6)] +:::code language="csharp" source="extensibility/samples/2.x/MiddlewareExtensibilitySample/Startup.cs" id="snippet1" highlight="6"::: -Both middlewares are registered in the request processing pipeline in `Startup.Configure`: +Both middleware are registered in the request processing pipeline in `Startup.Configure`: -[!code-csharp[](extensibility/samples/2.x/MiddlewareExtensibilitySample/Startup.cs?name=snippet2&highlight=13-14)] +:::code language="csharp" source="extensibility/samples/2.x/MiddlewareExtensibilitySample/Startup.cs" id="snippet2" highlight="13-14"::: ## IMiddlewareFactory @@ -125,9 +194,9 @@ Both middlewares are registered in the request processing pipeline in `Startup.C The default implementation, , is found in the [Microsoft.AspNetCore.Http](https://www.nuget.org/packages/Microsoft.AspNetCore.Http/) package. -:::moniker-end - ## Additional resources * * + +:::moniker-end diff --git a/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs b/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs index 7ef5adbce7..507afd408c 100644 --- a/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs +++ b/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs @@ -6,7 +6,7 @@ using MiddlewareExtensibilitySample.Models; namespace MiddlewareExtensibilitySample.Middleware { - #region snippet1 + // public class ConventionalMiddleware { private readonly RequestDelegate _next; @@ -35,5 +35,5 @@ namespace MiddlewareExtensibilitySample.Middleware await _next(context); } } - #endregion + // } diff --git a/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs b/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs index 67505b689c..e58471ad2e 100644 --- a/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs +++ b/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs @@ -6,7 +6,7 @@ using MiddlewareExtensibilitySample.Models; namespace MiddlewareExtensibilitySample.Middleware { - #region snippet1 + // public class FactoryActivatedMiddleware : IMiddleware { private readonly AppDbContext _db; @@ -35,5 +35,5 @@ namespace MiddlewareExtensibilitySample.Middleware await next(context); } } - #endregion + // } diff --git a/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs b/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs index 0b0219413a..e1e4f04482 100644 --- a/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs +++ b/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Builder; namespace MiddlewareExtensibilitySample.Middleware { - #region snippet1 + // public static class MiddlewareExtensions { public static IApplicationBuilder UseConventionalMiddleware( @@ -17,5 +17,5 @@ namespace MiddlewareExtensibilitySample.Middleware return builder.UseMiddleware(); } } - #endregion + // } diff --git a/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Startup.cs b/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Startup.cs index a04f55d7c6..0bce93c4ea 100644 --- a/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Startup.cs +++ b/aspnetcore/fundamentals/middleware/extensibility/samples/2.x/MiddlewareExtensibilitySample/Startup.cs @@ -11,7 +11,7 @@ namespace MiddlewareExtensibilitySample { public class Startup { - #region snippet1 + // public void ConfigureServices(IServiceCollection services) { services.AddDbContext(options => @@ -22,9 +22,9 @@ namespace MiddlewareExtensibilitySample services.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); } - #endregion + // - #region snippet2 + // public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) @@ -43,6 +43,6 @@ namespace MiddlewareExtensibilitySample app.UseStaticFiles(); app.UseMvc(); } - #endregion + // } } diff --git a/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs b/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs index 7ef5adbce7..507afd408c 100644 --- a/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs +++ b/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/ConventionalMiddleware.cs @@ -6,7 +6,7 @@ using MiddlewareExtensibilitySample.Models; namespace MiddlewareExtensibilitySample.Middleware { - #region snippet1 + // public class ConventionalMiddleware { private readonly RequestDelegate _next; @@ -35,5 +35,5 @@ namespace MiddlewareExtensibilitySample.Middleware await _next(context); } } - #endregion + // } diff --git a/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs b/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs index 67505b689c..e58471ad2e 100644 --- a/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs +++ b/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/FactoryActivatedMiddleware.cs @@ -6,7 +6,7 @@ using MiddlewareExtensibilitySample.Models; namespace MiddlewareExtensibilitySample.Middleware { - #region snippet1 + // public class FactoryActivatedMiddleware : IMiddleware { private readonly AppDbContext _db; @@ -35,5 +35,5 @@ namespace MiddlewareExtensibilitySample.Middleware await next(context); } } - #endregion + // } diff --git a/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs b/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs index 0b0219413a..e1e4f04482 100644 --- a/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs +++ b/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Middleware/MiddlewareExtensions.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Builder; namespace MiddlewareExtensibilitySample.Middleware { - #region snippet1 + // public static class MiddlewareExtensions { public static IApplicationBuilder UseConventionalMiddleware( @@ -17,5 +17,5 @@ namespace MiddlewareExtensibilitySample.Middleware return builder.UseMiddleware(); } } - #endregion + // } diff --git a/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Startup.cs b/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Startup.cs index fe57a2605f..004f4373b8 100644 --- a/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Startup.cs +++ b/aspnetcore/fundamentals/middleware/extensibility/samples/3.x/MiddlewareExtensibilitySample/Startup.cs @@ -10,7 +10,7 @@ namespace MiddlewareExtensibilitySample { public class Startup { - #region snippet1 + // public void ConfigureServices(IServiceCollection services) { services.AddDbContext(options => @@ -20,9 +20,9 @@ namespace MiddlewareExtensibilitySample services.AddRazorPages(); } - #endregion + // - #region snippet2 + // public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) @@ -45,6 +45,6 @@ namespace MiddlewareExtensibilitySample endpoints.MapRazorPages(); }); } - #endregion + // } }