1

我已经阅读了有关 IoC、DIP、DI 和服务定位器的各种文章,但我有点困惑,这是因为有些文章的示例过于模糊,而其他一些文章只有一些具体示例,而没有提及其他案例。

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

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

    class Consumer
    {
      public Consumer(IStore store){...}
    }
    ...
    
    Consumer c = new Consumer(new ConcreteStore());
    
  • 与第一个示例相同,但使用了一些 3rd 方库(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 Action):

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

    我添加了这个案例,因为文章Inversion of Control指出每个回调都是 IoC。这是真的吗?

4

2 回答 2

2

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

  1. 《穷人》DI
  2. 使用 IoC 容器的 DI
  3. 又是“穷人的”DI。无论您使用的是接口还是抽象类,DI 都可以工作。
  4. 方法注入
  5. 我不确定你在这里问什么。听起来您想在运行时更改 IWorld 的实例,这可能是属性注入而不是构造函数注入的情况。属性通常用于可选依赖项或可以更改的依赖项。然后在运行时使用服务定位器或其他方式设置该依赖关系取决于您。要考虑的另一件事是 IWorld 可能仅依赖于上下文,在这种情况下,您可以进行上下文相关的构造函数注入,其细节超出了此问题的范围。
  6. 与 DI 无关
于 2013-10-11T00:02:57.067 回答
1

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

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

要继续依赖解析器示例,您将所有相关类型注册到容器中,构建容器然后将其注册为依赖解析器。然后,asp.net mvc 框架使用解析器(服务定位器 - SL)来实例化控制器、视图和所有这些所需的 deps。

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

于 2013-10-08T07:55:30.620 回答