有没有理由不使用我的IoC作为一般设置存储库?

Geo*_*uer 5 inversion-of-control

假设ApplicationSettings类是应用于我的应用程序的设置的一般存储库,例如TimeoutPeriod,DefaultUnitOfMeasure,HistoryWindowSize等等......让我们说MyClass使用其中一个设置 - DefaultUnitOfMeasure.

我正确使用Inversion of Control Containers - 如果我错了,请纠正我 - 是你在构造函数中定义类的依赖关系:

public class MyClass {
  public MyClass(IDataSource ds, UnitOfMeasure default_uom) {...}
} 
Run Code Online (Sandbox Code Playgroud)

然后用类似的东西调用实例化你的类

var mc = IoC.Container.Resolve<MyClass>();
Run Code Online (Sandbox Code Playgroud)

其中的IDataSource已分配的具体实施和default_uom已经有线了从实例ApplicationSettings.DefaultUnitOfMeasure财产.然而,我不得不怀疑,如果所有这些篮球真的有必要跳过.我应该为自己做什么麻烦

public class MyClass {
  public MyClass(IDataSource ds) {
    UnitOfMeasure duom = IoC.Container.Resolve<UnitOfMeasure>("default_uom");
  }
} 
Run Code Online (Sandbox Code Playgroud)

是的,我的许多类最终都依赖于IoC.Container,但这是我的大多数类都会依赖的依赖项.只要类是耦合的,我似乎应该充分利用它.请敏捷的大师,告诉我哪里错了.

Bit*_*der 4

IoC.Container.Resolve(“default_uom”);

我认为这是一个经典的反模式,您使用 IoC 容器作为服务定位器 - 导致的关键问题是:

  • 如果您的容器配置错误,您的应用程序将不再快速失败(您只有在第一次尝试在代码中解析特定服务时才会知道这一点,除了一组特定的逻辑/情况之外,这种情况可能不会发生)。
  • 更难测试 - 当然不是不可能,但是您要么必须为测试创建一个真实的(半配置的)温莎容器实例,要么用 IWindsorContainer 的模拟注入单例 - 这给测试增加了很多摩擦,与仅能够通过构造函数/属性将模拟/存根服务直接传递到正在测试的类中相比。
  • 维护这种应用程序比较困难(配置不集中在一个位置)
  • 违反了许多其他软件开发原则(DRY、SOC 等)

原始声明中有关的部分暗示您的大多数类将依赖于您的 IoC 单例 - 如果它们通过构造函数/依赖项注入所有服务,那么与 IoC 的紧密耦合应该是例外规则 - 一般来说,我对容器的唯一依赖是当我在做一些棘手的事情时,即试图避免循环依赖问题,或者由于某种原因希望在运行时创建组件,即使这样我也可以通常避免依赖于通用 IServiceProvider 接口以外的任何东西,如果我需要在原始项目之外的环境中重用组件,则允许我交换自制的 IoC 或服务定位器实现。