【问题标题】:ASP.NET Core 5 - How to have optional dependencies?ASP.NET Core 5 - 如何拥有可选依赖项?
【发布时间】:2021-06-10 13:42:17
【问题描述】:

我正在开发一个中间件,我想对内部日志库有一个可选的依赖项。换句话说,如果MyLoggingService 已注册,那就太好了!否则,生活将继续,并且将 ill 登录到控制台。

但是通过声明public async Task Invoke(HttpContext httpContext, MyLoggingService logger),我收到一个运行时错误,说它没有注册。我尝试将默认值设置为null,但这不起作用。另外,因为它是一个中间件,我不能重载Invoke 方法。

除了请求服务集合,自己解决依赖之外,有没有其他的解决方案?

【问题讨论】:

  • 你可能真的发现了default interface implementation的用例
  • @Crowcoder 好吧,我以前读过,但是我根本不记得它。我不确定它将如何解决我未注册的服务运行时异常...

标签: c# .net dependency-injection asp.net-core-middleware


【解决方案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>();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      • 2018-02-11
      • 1970-01-01
      • 2015-11-11
      相关资源
      最近更新 更多