我正在开发一个中间件,我希望它对内部日志记录库有一个可选的依赖关系。换句话说,如果 MyLoggingService
已注册,太棒了!否则,生活还要继续,并会记录到控制台。
但是通过声明 public async Task Invoke(HttpContext httpContext, MyLoggingService logger)
,我收到一个运行时错误,说它没有注册。我尝试将默认值设置为 null
但这没有用。另外,因为它是一个中间件,我不能重载 Invoke
方法。
除了请求服务集合并自己解决依赖项之外,还有其他解决方案吗?
最佳答案
与其将依赖项设为可选,不如考虑:
IMyLoggingService
例如:
public class CustomMiddleware1 : IMiddleware
{
private readonly IMyLoggingService logger;
public CustomMiddleware1(IMyLoggingService logger) => this.logger = logger;
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
this.logger.Log("Before");
await next(context);
this.logger.Log("After");
}
}
空对象实现:public sealed class NullMyLoggingService : IMyLoggingService
{
public void Log(LogEntry e) { }
}
注册:services.AddSingleton<IMyLoggingService>(new NullMyLoggingService());
app.Use<CustomMiddleware1>();
调用 AddSingleton<IMyLoggingService>(new NullMyLoggingService())
确保注册 IMyLoggingService
永远存在。这防止了消费者的复杂性,否则他们将不得不为记录器不存在的情况添加条件逻辑。可以通过简单地添加第二个
IMyLoggingService
来替换此 null 实现。在第一个之后:services.AddScoped<IMyLoggingService, DbMyLoggingService>();
app.Use<CustomMiddleware1>();
关于c# - ASP.NET Core 5 - 如何拥有可选的依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66601594/