使用 ASP.NET Core 中的第三方容器激活中间件Middleware activation with a third-party container in ASP.NET Core
本文内容
本文演示如何使用 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 存储库。
IMiddlewareFactoryIMiddlewareFactory
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.
}
}
IMiddlewareIMiddleware
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 存储库。
IMiddlewareFactoryIMiddlewareFactory
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.
}
}
IMiddlewareIMiddleware
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();
}