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&lt;IMyLoggingService&gt;(new NullMyLoggingService()) 的调用确保IMyLoggingService 的注册始终存在。这可以防止消费者变得复杂,否则他们必须为记录器不存在的情况添加条件逻辑。

只需在第一个 IMyLoggingService 之后添加第二个 IMyLoggingService 即可替换此 null 实现:

services.AddScoped<IMyLoggingService, DbMyLoggingService>();

app.Use<CustomMiddleware1>();

【讨论】:

以上是关于ASP.NET Core 5 - 如何拥有可选依赖项?的主要内容,如果未能解决你的问题,请参考以下文章

小5聊Asp.Net Core 2.1 主要依赖那些dll和版本

3 .NET Core笔试题

如何解决 ASP.NET Core 中的依赖问题

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)

如何在 ASP.NET CORE 中使用具有依赖注入的动作过滤器?

.NET开发技能:容器化ASP.NET Core?