命名对象列表的 IoC

IoC for a list of named objects

我正在寻找有关此问题的建议,以及 service locator 和 class 命名约定是否是一个好的解决方案(我倾向于避免这些反模式),以及潜在的性能影响。

一个应用程序有一组实现相同接口的对象,按名称区分。例如:

 public interface IDog  {
      void Bark();
 }

 public class Pug: IDog {
      public void Bark() {
         // Pug bark implementation
      }
 }

 public class Beagle: IDog {
      public void Bark() {
         // Beagle bark implementation
      }
 }

在代码中,当你需要一个IDog时,你只知道传递给你的一个字符串名称,例如"Pug"或"Beagle"。在这种情况下,字符串可能包含特殊字符(例如:<breed:pug />) 已经提出了一些建议的解决方案:

  1. 使用反射,在字符串名称 == 实现名称处找到所需的实现。
  2. 为每个 class 添加一个 addribute,使用反射 where string name == attribute 属性。例如 [DogBreed("Pug")]
  3. 添加品种 属性 到 IDog 界面。将 IList 注入工厂 class,并让它检索匹配的狗。前任。

    Private IList _dogs; Public DogFactory(IList<IDog> dogs) { _dogs = dogs; } Public IDog GetDog(string dogBreed) { return _dogs.First(x => x.Breed == dogBreed); }

1 和 2 使用服务定位器。 1 使用隐含的命名约定,您只有通过查看反射代码才能知道。 3 问题是所有对象都将构建在内存中,即使您只需要一个实现。

我个人过去倾向于#3。对象创建应该是廉价的。然而,这是一个遗留的网络应用程序,链下的对象可能有很高的初始化成本。此应用程序将 Unity 用于 IoC。

选项 1.

这个选项听起来像 Partial Type Name Role Hint 成语。如果你注入候选列表并在这些候选中找到合适的策略,它只是普通的旧构造函数注入,与服务定位器无关(这是一件好事)。

选项 2.

这个选项听起来像 Metadata Role Hint 成语。同样,如果您通过构造函数注入候选列表,则服务定位器将无处可见。

选项 3.

这个选项听起来像是 Role Interface Role Hint 成语的变体。仍然支持使用良好的旧构造函数注入。


就个人而言,我倾向于支持部分类型名称角色提示,因为这种设计不会影响任何业务逻辑的实现。所有选择逻辑都成为纯粹的基础架构问题,并且可以 独立于 实现和客户端定义。

说到组成相关对象图的成本,有办法address any issues in clean ways