对 DI、IoC 和服务定位器的困惑

本文关键字:定位器 服务 DI IoC | 更新日期: 2023-09-27 18:34:32

我已经阅读了有关IoC,dip,DI和服务定位器的各种文章,但我有点困惑,这是因为有些文章的例子太模糊,而其他一些文章只有一些具体的例子,没有提到其他情况。

您能否为我澄清这一点,看看下面的示例并简要解释哪些示例与哪种模式匹配?

  • 手动将接口传递给构造函数:

    class Consumer
    {
      public Consumer(IStore store){...}
    }
    ...
    Consumer c = new Consumer(new ConcreteStore());
    
  • 与第一个示例相同,但使用了一些第三方库(Unity,Windsor,Ninject(

  • 与第一个示例相同,但使用 BaseStore 类而不是 IStore 接口

  • 将依赖项传递给其他方法,而不是构造函数:

    class Consumer
    {
      public BySomething(IStore store){...}
    }
    ...
    Consumer c = new Consumer();
    c.BySomething(new ConcreteStore());
    
  • 传递在其他接口中屏蔽的依赖项(此解决方案的奖励 - 当在"世界"中发明了一些其他东西并且消费者希望使用它们时,我们不必更改构造函数参数,而只需更新 IWorld;我们可以在测试时完全用其他东西替换整个世界(:

    interface IWorld
    {
      IDictionary<string,IStore> Stores { get; set; }
      IDictionary<string,ICityMap> Maps { get; set; }
      ...
    }
    class Consumer
    {
      public Consumer(IWorld world){...}
      public BySomething(string store, string city){...}
    }
    ...
    IWorld myWorld = new HeavenlyWorld();
    ... // adding stores, maps and whatnot
    Consumer c = new Consumer(myWorld);
    

    一个子问题:在这种情况下,IWorld 是否完全是服务定位器?

  • 传递回调函数或委托(在本例中为 .NET 操作(:

    c.BySomething(store, city, new Action(() => {...} ));
    

    我添加了这种情况,因为文章控制反转指出每个回调都是 IoC。是真的吗?

对 DI、IoC 和服务定位器的困惑

您列出的所有内容都是依赖注入的一种形式。

  1. "穷人的"DI
  2. 使用 IoC 容器的 DI
  3. "穷人的"DI又来了。无论您使用的是接口还是抽象类,DI 都有效。
  4. 方法注入
  5. 我不确定你在这里问什么。听起来您想在运行时更改 IWorld 的实例,这可能是属性注入而不是构造函数注入的情况。属性通常用于可选依赖项或可以更改的依赖项。然后,是否在运行时使用服务定位器或其他方式设置该依赖项取决于您。要考虑的另一件事是,IWorld 可能只依赖于上下文,在这种情况下,您可以进行上下文降级构造函数注入,其细节超出了本文的范围。
  6. 与 DI 无关

每次将依赖项作为构造函数/方法参数传递时,这就是依赖项注入。它可以是手动的,就像在大多数示例中一样,也可以使用 DI 容器(又名 IoC 容器(自动执行。

使用容器意味着使用 deps 的对象由容器构造。您可以直接向容器请求该服务,在这种情况下,有一个静态属性或方法(想想 asp.net mvc 中的 DependecyResolver(公开该服务。在这种情况下,您使用的是服务定位器模式。在您的示例中,IWork 不是定位器,它只是一个依赖项。

若要继续依赖项解析程序示例,请将所有相关类型注册到容器中,生成容器,然后注册为依赖项解析程序。然后,asp.net mvc 框架使用解析器(服务定位器 - SL(来实例化控制器、视图以及它们所需的所有部门。

使用 SL 模式作为框架的一部分是可以的,但如果在应用中使用它来实例化对象,则不行,因为它将代码耦合到定位器。有时是唯一的解决方案,但 99% 你只是一个反模式。