[英]Configure Simple Injector to support resolving ASP.NET Core middleware dependencies?
如何配置SimpleInjector來解決LogMiddleware的Invoke方法依賴關系,例如IMessageService?
據我所知,Asp.net核心使用HttpContext.RequestServices(IServiceProvider)來解決依賴關系,我將SimpleInjector容器設置為HttpContext.RequestServices屬性,但是沒有用。 我想動態更改ServiceProvider,因為每個租戶都應該有一個容器。
public class LogMiddleware
{
RequestDelegate next;
private readonly ILogger log;
public LogMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
{
this.next = next;
this.log = loggerFactory.CreateLogger<LogMiddleware>();
}
public async Task Invoke(HttpContext context, IMessageService messageService)
{
await context.Response.WriteAsync(
messageService.Format(context.Request.Host.Value));
}
}
public interface IMessageService
{
string Format(string message);
}
public class DefaultMessageService : IMessageService
{
public string Format(string message)
{
return "Path:" + message;
}
}
您可以如下使用LogMiddleware
類:
applicationBuilder.Use(async (context, next) => {
var middleware = new LogMiddleware(
request => next(),
applicationBuilder.ApplicationServices.GetService<ILoggerFactory>());
await middleware.Invoke(context, container.GetInstance<IMessageService>());
});
但是,我建議您稍微更改一下中間件類。 將運行時數據( next()
委托)移出構造函數(因為在構造過程中組件不需要運行時數據 ),然后將IMessageService
依賴項移入構造函數。 並將ILoggerFactory
替換為ILogger
依賴項,因為注入構造函數只需要存儲其傳入的依賴項即可 (或將ILogger
替換為您自己的特定於應用程序的記錄器抽象 )。
您的中間件類將如下所示:
public sealed class LogMiddleware
{
private readonly IMessageService messageService;
private readonly ILogger log;
public LogMiddleware(IMessageService messageService, ILogger log) {
this.messageService = messageService;
this.log = log;
}
public async Task Invoke(HttpContext context, Func<Task> next) {
await context.Response.WriteAsync(
messageService.Format(context.Request.Host.Value));
await next();
}
}
這使您可以如下使用中間件:
var factory = applicationBuilder.ApplicationServices.GetService<ILoggerFactory>();
applicationBuilder.Use(async (context, next) => {
var middleware = new LogMiddleware(
container.GetInstance<IMessageService>(),
factory.CreateLogger<LogMiddleware>());
await middleware.Invoke(context, next);
});
或者,如果您在Simple Injector中注冊了ILogger
(或您的自定義日志記錄抽象),則可以執行以下操作:
applicationBuilder.Use(async (context, next) => {
var middleware = container.GetInstance<LogMiddleware>();
await middleware.Invoke(context, next);
});
您的代碼有兩個問題。
public class DefaultMessageService : IMessageService { public string Format(string message) { return "Path:" + message; } }
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(); services.AddSingleton<IMessageService>(new DefaultMessageService()); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.