- 全球化与本土化
- 性能
- 高级
使用 ASP.NET Core 中的第三方容器激活中间件
作者:Luke Latham
本文演示如何使用 IMiddlewareFactory 和 IMiddleware 作为使用第三方容器激活中间件的可扩展点。 有关 IMiddlewareFactory
和 IMiddleware
的入门信息,请参阅 ASP.NET Core 中基于工厂的中间件激活。
示例应用演示了使用 IMiddlewareFactory
、SimpleInjectorMiddlewareFactory
实现激活的中间件。 此示例使用 Simple Injector 依赖项注入 (DI) 容器。
此示例的中间件实现记录了查询字符串参数 (key
) 提供的值。 中间件使用插入的数据库上下文(有作用域的服务)将查询字符串值记录在内存中数据库。
备注
此示例应用仅出于演示目的使用 Simple Injector。 不认可使用 Simple Injector。 Simple Injector 文档中描述的中间件激活方法和 Simple Injector 维护人员推荐的 GitHub 问题。 有关详细信息,请参阅 Simple Injector 文档和 Simple Injector GitHub 存储库。
IMiddlewareFactory
IMiddlewareFactory 提供中间件的创建方法。
在示例应用中,实现了中间件工厂以创建 SimpleInjectorActivatedMiddleware
实例。 中间件工厂使用 Simple Injector 容器来解析中间件:
public class SimpleInjectorMiddlewareFactory : IMiddlewareFactory { private readonly Container _container; public SimpleInjectorMiddlewareFactory(Container container) { _container = container; } public IMiddleware Create(Type middlewareType) { return _container.GetInstance(middlewareType) as IMiddleware; } public void Release(IMiddleware middleware) { // The container is responsible for releasing resources. } }
IMiddleware
IMiddleware 定义应用的请求管道的中间件。
由 IMiddlewareFactory
实现 (Middleware/SimpleInjectorActivatedMiddleware.cs) 激活的中间件 :
public class SimpleInjectorActivatedMiddleware : IMiddleware { private readonly AppDbContext _db; public SimpleInjectorActivatedMiddleware(AppDbContext db) { _db = db; } public async Task InvokeAsync(HttpContext context, RequestDelegate next) { var keyValue = context.Request.Query["key"]; if (!string.IsNullOrWhiteSpace(keyValue)) { _db.Add(new Request() { DT = DateTime.UtcNow, MiddlewareActivation = "SimpleInjectorActivatedMiddleware", Value = keyValue }); await _db.SaveChangesAsync(); } await next(context); } }
为中间件创建扩展 (Middleware/MiddlewareExtensions.cs) :
public static class MiddlewareExtensions { public static IApplicationBuilder UseSimpleInjectorActivatedMiddleware( this IApplicationBuilder builder) { return builder.UseMiddleware<SimpleInjectorActivatedMiddleware>(); } }
Startup.ConfigureServices
必须执行多项任务:
- 设置 Simple Injector 容器。
- 注册工厂和中间件。
- 使 Simple Injector 容器提供应用的数据库上下文。
public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); // Replace the default middleware factory with the // SimpleInjectorMiddlewareFactory. services.AddTransient<IMiddlewareFactory>(_ => { return new SimpleInjectorMiddlewareFactory(_container); }); // Wrap ASP.NET Core requests in a Simple Injector execution // context. services.UseSimpleInjectorAspNetRequestScoping(_container); // Provide the database context from the Simple // Injector container whenever it's requested from // the default service container. services.AddScoped<AppDbContext>(provider => _container.GetInstance<AppDbContext>()); _container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle(); _container.Register<AppDbContext>(() => { var optionsBuilder = new DbContextOptionsBuilder<DbContext>(); optionsBuilder.UseInMemoryDatabase("InMemoryDb"); return new AppDbContext(optionsBuilder.Options); }, Lifestyle.Scoped); _container.Register<SimpleInjectorActivatedMiddleware>(); _container.Verify(); }
中间件在 Startup.Configure
的请求处理管道中注册:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); } app.UseSimpleInjectorActivatedMiddleware(); app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); }
本文演示如何使用 IMiddlewareFactory 和 IMiddleware 作为使用第三方容器激活中间件的可扩展点。 有关 IMiddlewareFactory
和 IMiddleware
的入门信息,请参阅 ASP.NET Core 中基于工厂的中间件激活。
示例应用演示了使用 IMiddlewareFactory
、SimpleInjectorMiddlewareFactory
实现激活的中间件。 此示例使用 Simple Injector 依赖项注入 (DI) 容器。
此示例的中间件实现记录了查询字符串参数 (key
) 提供的值。 中间件使用插入的数据库上下文(有作用域的服务)将查询字符串值记录在内存中数据库。
备注
此示例应用仅出于演示目的使用 Simple Injector。 不认可使用 Simple Injector。 Simple Injector 文档中描述的中间件激活方法和 Simple Injector 维护人员推荐的 GitHub 问题。 有关详细信息,请参阅 Simple Injector 文档和 Simple Injector GitHub 存储库。
IMiddlewareFactory
IMiddlewareFactory 提供中间件的创建方法。
在示例应用中,实现了中间件工厂以创建 SimpleInjectorActivatedMiddleware
实例。 中间件工厂使用 Simple Injector 容器来解析中间件:
public class SimpleInjectorMiddlewareFactory : IMiddlewareFactory { private readonly Container _container; public SimpleInjectorMiddlewareFactory(Container container) { _container = container; } public IMiddleware Create(Type middlewareType) { return _container.GetInstance(middlewareType) as IMiddleware; } public void Release(IMiddleware middleware) { // The container is responsible for releasing resources. } }
IMiddleware
IMiddleware 定义应用的请求管道的中间件。
由 IMiddlewareFactory
实现 (Middleware/SimpleInjectorActivatedMiddleware.cs) 激活的中间件 :
public class SimpleInjectorActivatedMiddleware : IMiddleware { private readonly AppDbContext _db; public SimpleInjectorActivatedMiddleware(AppDbContext db) { _db = db; } public async Task InvokeAsync(HttpContext context, RequestDelegate next) { var keyValue = context.Request.Query["key"]; if (!string.IsNullOrWhiteSpace(keyValue)) { _db.Add(new Request() { DT = DateTime.UtcNow, MiddlewareActivation = "SimpleInjectorActivatedMiddleware", Value = keyValue }); await _db.SaveChangesAsync(); } await next(context); } }
为中间件创建扩展 (Middleware/MiddlewareExtensions.cs) :
public static class MiddlewareExtensions { public static IApplicationBuilder UseSimpleInjectorActivatedMiddleware( this IApplicationBuilder builder) { return builder.UseMiddleware<SimpleInjectorActivatedMiddleware>(); } }
Startup.ConfigureServices
必须执行多项任务:
- 设置 Simple Injector 容器。
- 注册工厂和中间件。
- 使 Simple Injector 容器提供应用的数据库上下文。
public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); // Replace the default middleware factory with the // SimpleInjectorMiddlewareFactory. services.AddTransient<IMiddlewareFactory>(_ => { return new SimpleInjectorMiddlewareFactory(_container); }); // Wrap ASP.NET Core requests in a Simple Injector execution // context. services.UseSimpleInjectorAspNetRequestScoping(_container); // Provide the database context from the Simple // Injector container whenever it's requested from // the default service container. services.AddScoped<AppDbContext>(provider => _container.GetInstance<AppDbContext>()); _container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle(); _container.Register<AppDbContext>(() => { var optionsBuilder = new DbContextOptionsBuilder<DbContext>(); optionsBuilder.UseInMemoryDatabase("InMemoryDb"); return new AppDbContext(optionsBuilder.Options); }, Lifestyle.Scoped); _container.Register<SimpleInjectorActivatedMiddleware>(); _container.Verify(); }
中间件在 Startup.Configure
的请求处理管道中注册:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); } app.UseSimpleInjectorActivatedMiddleware(); app.UseStaticFiles(); app.UseMvc(); }
其他资源
下一篇:没有了