【问题标题】:Abstractions, solid and property injection vs constructor injection抽象、实体和属性注入与构造函数注入
【发布时间】:2018-11-07 21:53:25
【问题描述】:

我在工作中与某人进行了讨论。类和接口如下所示:

public interface ISomeInterface { }

public class ImplementationOfInterface : ISomeInterface { }

public class ClassThatUsesInterface {
    private ISomeInterface _interface;

    public ISomeInterface Interface {
         get => _interface ?? new ImplementationOfInterface();
         set => _interface = value;
    }
}

99% 的时间我们会使用ImplementationOfInterface。最后 1% 可能是单元测试的目的。

我已经尝试阅读依赖注入、依赖倒置原则、服务、SOLID 以及更多不相关的内容,如服务定位器模式/反模式、两步初始化反模式等,但没有找到任何人描述这样做的方式。

违反了 SOLID 中的 D 已半明半白; 《依赖倒置原则; 一个人应该“依赖于抽象,[而不是]具体化。”。因为在单元测试中覆盖它或者如果你愿意的话切换实现是相当容易的......这让我更加困惑......

即使它可能与 SOLID 中的 D 相冲突,并且在正确的依赖注入之后并没有真正做任何事情,但真的很难反对这种用法。

我个人建议通过构造函数注入实例,但同事认为这样的工作量太大,看不到好处。老实说,我很难不同意,但我仍然对此有不好的预感..

你能提出文章或有力的论据来支持和反对使用这种特殊的“黑客”吗?

【问题讨论】:

  • 注意 SOLID 中的 S 也是踩到的,尤其是当 ImplementationOfInterface 为 IDisposable 或有构造参数时。管理生命周期或依赖关系不是 ClassThatUsesInterface 的任务。

标签: c# oop design-patterns architecture


【解决方案1】:

ClassThatUsesInterface 甚至需要知道 ImplementationOfInterface 存在这一事实是代码异味。您可能需要为一些完全不相关的命名空间添加一个using 指令以进行编译,甚至可能是对某个其他项目或包或dll 的引用。因此,您的代码开始纠结,并且您的依赖项开始令人头疼。

我意识到这是一个精简的演示示例,但 ImplementationOfInterface 只是 碰巧 本身没有依赖关系。如果真的发生了怎么办?你会new那些反过来吗?和他们的依赖..?这表明您在这里违反了另一个 SOLID 原则 - 每次将 ctor 参数更改为 ImplementationOfInterface 时,您都需要修改此类。这违反了开放/封闭原则。

【讨论】:

  • 喜欢这个......这是 100% 正确的,一个非常精简的版本,是的,以下所有课程都遵循相同的模式。他们都在公共属性中更新了他们的依赖项......
【解决方案2】:

使用构造函数注入依赖。您不希望允许在 ClassThatUsesInterface 实例的生命周期中更改实现

请注意,某些 DI 框架或实现不支持属性注入。比如 Asp.Net Core。

另外,像现在这样使用该属性,您必须对该属性的默认实现(该类不应该知道,您现在正在耦合它)没有设置,因为它是隐藏的。而如果你显式使用构造函数,那么所有人都清楚。

【讨论】:

  • 很好的论据。但恐怕它不会改变我的同事的想法......我需要更多......我们的对象的生命周期很短,因为它们经常根据网络请求而存在......尽管可能,我担心这个仅论点就没有什么意义了:(
  • 为什么你认为生命周期是相关的?几乎所有 APS.NET 对象都有请求范围。
  • @bommelding 不确定他是否在使用 asp.net
  • @bommelding:确实应该不相关,但这可能是我的同事们会提出的论点。
  • @PeterBons 我们混合使用网页(各种类型,razor.net asp.net++)、nservicebuses、命令行工具、windows 服务和 msmq 消息...相当的负载...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多