IoC用于命名对象列表

时间:2015-06-02 11:57:12

标签: inversion-of-control unity-container factory-pattern

我正在寻找有关此问题的建议以及service locator和类命名约定是否正常(我倾向于避免这些反模式)以及潜在的性能后果。

应用程序具有实现相同界面的对象集合,按名称区分。例如:

 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. 为每个类添加一个addribute,在string name == attribute property中使用reflection。前[DogBreed(“Pug”)]
  3. 将一个Breed属性添加到IDog界面。将IList注入工厂类,并让它检索匹配的狗。防爆。

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

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

    我个人过去曾倾向于#3。对象创建应该很便宜。但是,这是一个遗留的Web应用程序,链中的对象可能会有很大的初始化成本。此应用程序使用Unity for IoC。

1 个答案:

答案 0 :(得分:3)

选项1。

此选项听起来像Partial Type Name Role Hint成语。如果您注入候选人列表并在这些候选人中找到适当的策略,那么它只是简单的构造函数注入,并且与Service Locator无关(这是一件好事)。

选项2。

此选项听起来像Metadata Role Hint成语。同样,如果您通过构造函数注入候选列表,则无法看到Service Locator。

选项3。

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

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

当涉及到撰写相关对象图的成本时,有address any issues in clean ways的方法。