ASP.NET Core 5 - 如何拥有可选依赖项?
Posted
技术标签:
【中文标题】ASP.NET Core 5 - 如何拥有可选依赖项?【英文标题】:ASP.NET Core 5 - How to have optional dependencies? 【发布时间】:2021-06-10 13:42:17 【问题描述】:我正在开发一个中间件,我想对内部日志库有一个可选的依赖项。换句话说,如果MyLoggingService
已注册,那就太好了!否则,生活将继续,并且将 ill 登录到控制台。
但是通过声明public async Task Invoke(HttpContext httpContext, MyLoggingService logger)
,我收到一个运行时错误,说它没有注册。我尝试将默认值设置为null
,但这不起作用。另外,因为它是一个中间件,我不能重载Invoke
方法。
除了请求服务集合,自己解决依赖之外,有没有其他的解决方案?
【问题讨论】:
你可能真的发现了default interface implementation的用例 @Crowcoder 好吧,我以前读过,但是我根本不记得它。我不确定它将如何解决我未注册的服务运行时异常... 【参考方案1】:答案非常简单:
public async Task Invoke(HttpContext httpContext, MyLoggingService logger = null)
【讨论】:
【参考方案2】:不要让依赖项成为可选,而是考虑:
编程到抽象,例如IMyLoggingService
注册Null Object 实现
例如:
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
之后添加第二个 IMyLoggingService
即可替换此 null 实现:
services.AddScoped<IMyLoggingService, DbMyLoggingService>();
app.Use<CustomMiddleware1>();
【讨论】:
以上是关于ASP.NET Core 5 - 如何拥有可选依赖项?的主要内容,如果未能解决你的问题,请参考以下文章
小5聊Asp.Net Core 2.1 主要依赖那些dll和版本
ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)