c# - ASP.NET Core 5 - 如何拥有可选的依赖项?

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

我正在开发一个中间件,我希望它对内部日志记录库有一个可选的依赖关系。换句话说,如果 MyLoggingService已注册,太棒了!否则,生活还要继续,并会记录到控制台。
但是通过声明 public async Task Invoke(HttpContext httpContext, MyLoggingService logger) ,我收到一个运行时错误,说它没有注册。我尝试将默认值设置为 null但这没有用。另外,因为它是一个中间件,我不能重载 Invoke方法。
除了请求服务集合并自己解决依赖项之外,还有其他解决方案吗?

最佳答案

与其将依赖项设为可选,不如考虑:

  • 编程到抽象,例如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 来替换此 null 实现。在第一个之后:
    services.AddScoped<IMyLoggingService, DbMyLoggingService>();
    
    app.Use<CustomMiddleware1>();
    

    关于c# - ASP.NET Core 5 - 如何拥有可选的依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66601594/

    相关文章:

    c# - ClientScript 不适用于 AJAX UpdateProgress

    c# - 将点对象添加到 ZedGraph

    c# - 如何使用 C# 检查用户是否在 Active Directory 中具有写权限?

    ios - 为什么 .net maui 应用程序在 iOS 设备上崩溃?

    wcf - 带有 WCF4 自托管服务的 Autofac(无 .svc)

    java - @PostConstruct 的顺序和继承

    c# - MySQL ODBC 存储过程结果缺少列

    c# - 如何从 C# 中的 FTP 请求获取 IP 地址

    .net - 对 WCF 服务的异步调用以静默方式随机失败

    c++ - C++ 中的依赖注入(inject)