我正在寻找有关此问题的建议以及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 />
)
提出了一些解决方案:
将一个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);
}
1和2使用服务定位器。 1使用隐含的命名约定,只有通过查看反射代码才能知道。 3关注的是,即使您只需要一个实现,所有对象都将构建在内存中。
我个人过去曾倾向于#3。对象创建应该很便宜。但是,这是一个遗留的Web应用程序,链中的对象可能会有很大的初始化成本。此应用程序使用Unity for IoC。
答案 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的方法。