【问题标题】:Dependency injection with constructor chaining使用构造函数链接的依赖注入
【发布时间】:2020-10-01 08:04:42
【问题描述】:

目前我有一个简单的通用抽象类,在构造函数中有一个服务参数,通过依赖注入解决。

public abstract class CosmosCommandHandler<T>
{
    protected readonly ICosmosStore<T> _cosmosStore;

    protected CosmosCommandHandler(ICosmosStore<T> cosmosStore)
    {
      _cosmosStore = cosmosStore;
    }
}

还有一些继承自它的具体类

public class FooCommandHandler : CosmosCommandHandler<Foo> 
{
  private readonly IFooService _fooService;

  public FooCommandHandler(ICosmosStore<Foo> cosmosStore, IFooService fooService) 
      : base(cosmosStore)
  {
    _fooService = fooService;
  }
}

这一切都很好,但我想向抽象类添加一个新服务并用 DI 来解决它。我的想法是我应该为此使用构造函数链接,但它没有成功。 像这样的。

public abstract class CosmosCommandHandler<T>
{
    private readonly IAuditService _auditService;
    protected readonly ICosmosStore<T> _cosmosStore;

    private CosmosCommandHandler(ICosmosStore<T> cosmosStore, IAuditService auditService)
    {
        _cosmosStore = cosmosStore;
        _auditService = auditService;
    }

    protected CosmosCommandHandler(ICosmosStore<T> cosmosStore) 
        : this(cosmosStore, IAuditService auditService)
    {
    }
}

显然我可以像ICosmosStore 一样从FooCommandHandler 传递IAuditService,但这似乎不对,因为FooCommandHandlerIAuditService 无关。它超出了它的范围。

这有可能实现吗?

【问题讨论】:

  • 不,你问的是不可能的。您可以为此使用组合而不是继承。
  • 如果FooCommandHandler 不需要IAuditService 那么我会质疑你的设计。
  • @JohnathanBarclay IAuditService 就像一个记录器,它周围的一切都只能在基类中实现。这是较低的水平。命令处理程序不应该知道有关此服务的任何信息,因为它将完全在基类中处理。对我来说似乎没问题,但如果你仍然认为这有问题,你能详细说明一下吗?
  • 派生类在设计上与它们的基类紧密耦合,因此您对命令处理程序不了解此服务的任何假设是非常不稳定的。即使我们忽略了你自己发现的构造函数问题,如果你例如覆盖任何基本方法,您仍然需要调用 base 来处理日志记录,对吗?所以命令处理程序实际上确实偷偷知道。否则,您有一个基类,您不会覆盖派生类中的任何内容,这再次引出了为什么不使用组合来代替的问题?
  • 在你的设计中FooCommandHandler一个CosmosCommandHandler&lt;Foo&gt;,所以要实例化一个FooCommandHandler,你需要提供一个IAuditService。如果FooCommandHandler 需要 CosmosCommandHandler&lt;Foo&gt; 然后使用组合。

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


【解决方案1】:

如果IAuditService 超出FooCommandHandler 范围,则创建CosmosCommandHandler 类的子类,该类将具有IAuditService。而那个孩子也可以是抽象类。 此外,您可以为您的 CosmosCommandHandler 类创建额外的重载构造函数 - 而 FooCommandHandler 类不需要使用它。但这也打破了继承的概念,因为FooCommandHandler 类与IAuditService 无关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-02
    • 2023-03-08
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    相关资源
    最近更新 更多