Ativação de middleware com um contêiner de terceiros no ASP.NET Core
Observação
Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Este artigo demonstra como usar o IMiddlewareFactory e o IMiddleware como um ponto de extensibilidade para a ativação do middleware com um contêiner de terceiros. Para obter informações introdutórias sobre o IMiddlewareFactory
e o IMiddleware
, confira o tópico Ativação de middleware baseada em alocador no ASP.NET Core.
Exibir ou baixar código de exemplo (como baixar)
O aplicativo de exemplo demonstra a ativação do middleware por uma implementação de IMiddlewareFactory
, SimpleInjectorMiddlewareFactory
. O exemplo usa o contêiner de DI (injeção de dependência) Simple Injector.
A implementação do middleware do exemplo registra o valor fornecido por um parâmetro de cadeia de consulta (key
). O middleware usa um contexto de banco de dados injetado (um serviço com escopo) para registrar o valor da cadeia de consulta em um banco de dados em memória.
Observação
O aplicativo de exemplo usa o Simple Injector simplesmente para fins de demonstração. O uso do Simple Injector não é um endosso. As abordagens de ativação do middleware descritas na documentação do Simple Injector e nos problemas do GitHub são recomendadas pelos mantenedores do Simple Injector. Para obter mais informações, confira a Documentação do Simple Injector e o repositório do GitHub do Simple Injector.
IMiddlewareFactory
IMiddlewareFactory fornece métodos para a criação do middleware.
No aplicativo de amostra, um alocador de middleware é implementado para criar uma instância de SimpleInjectorActivatedMiddleware
. O alocador de middleware usa o contêiner do Simple Injector para resolver o middleware:
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 define o middleware para o pipeline de solicitação do aplicativo.
Middleware ativado por uma implementação de 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);
}
}
Uma extensão é criada para o middleware (Middleware/MiddlewareExtensions.cs
):
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseSimpleInjectorActivatedMiddleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<SimpleInjectorActivatedMiddleware>();
}
}
O Startup.ConfigureServices
precisa executar várias tarefas:
- Configure o contêiner do Simple Injector.
- Registre o alocador e o middleware.
- Disponibilize o contexto do banco de dados do aplicativo por meio do contêiner do 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();
}
O middleware é registrado no pipeline de processamento da solicitação em 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();
});
}
Este artigo demonstra como usar o IMiddlewareFactory e o IMiddleware como um ponto de extensibilidade para a ativação do middleware com um contêiner de terceiros. Para obter informações introdutórias sobre o IMiddlewareFactory
e o IMiddleware
, confira o tópico Ativação de middleware baseada em alocador no ASP.NET Core.
Exibir ou baixar código de exemplo (como baixar)
O aplicativo de exemplo demonstra a ativação do middleware por uma implementação de IMiddlewareFactory
, SimpleInjectorMiddlewareFactory
. O exemplo usa o contêiner de DI (injeção de dependência) Simple Injector.
A implementação do middleware do exemplo registra o valor fornecido por um parâmetro de cadeia de consulta (key
). O middleware usa um contexto de banco de dados injetado (um serviço com escopo) para registrar o valor da cadeia de consulta em um banco de dados em memória.
Observação
O aplicativo de exemplo usa o Simple Injector simplesmente para fins de demonstração. O uso do Simple Injector não é um endosso. As abordagens de ativação do middleware descritas na documentação do Simple Injector e nos problemas do GitHub são recomendadas pelos mantenedores do Simple Injector. Para obter mais informações, confira a Documentação do Simple Injector e o repositório do GitHub do Simple Injector.
IMiddlewareFactory
IMiddlewareFactory fornece métodos para a criação do middleware.
No aplicativo de amostra, um alocador de middleware é implementado para criar uma instância de SimpleInjectorActivatedMiddleware
. O alocador de middleware usa o contêiner do Simple Injector para resolver o middleware:
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 define o middleware para o pipeline de solicitação do aplicativo.
Middleware ativado por uma implementação de 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);
}
}
Uma extensão é criada para o middleware (Middleware/MiddlewareExtensions.cs
):
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseSimpleInjectorActivatedMiddleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<SimpleInjectorActivatedMiddleware>();
}
}
O Startup.ConfigureServices
precisa executar várias tarefas:
- Configure o contêiner do Simple Injector.
- Registre o alocador e o middleware.
- Disponibilize o contexto do banco de dados do aplicativo por meio do contêiner do 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();
}
O middleware é registrado no pipeline de processamento da solicitação em Startup.Configure
:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseSimpleInjectorActivatedMiddleware();
app.UseStaticFiles();
app.UseMvc();
}