我喜欢ASP.NET Core的DI功能,但是发现我的某些类最终都带有巨大的构造函数参数签名...
public class Foo {
private IBar1 _bar1;
private IBar2 _bar2;
// lots more here...
public Foo(IBar1 bar1, IBar2 bar2, lots more here...) {
_Bar1 = bar1;
_Bar2 = bar2;
// ...
}
public DoSomething() {
// Use _bar1
}
}
如果这看起来像是代码气味,则需要指出的是,任何控制器都将使用AutoMapper,电子邮件服务以及与ASP.NET Identity相关的2或3个管理器,因此在开始之前我有4或5个依赖项注入单个存储库。即使我只使用2个存储库,在没有实际违反任何SOLID原则的情况下,也可以得到6或7个依赖项。
我想知道是否使用参数对象。我可以创建一个对我的应用程序中每个注入的依赖项都具有公共属性的类,为每个注入一个构造函数参数,然后将其注入到每个类中,而不是注入所有单独的Bars ...
public class Foo {
private IAllBars _allBars;
public Foo(IAllBars allBars) {
_allBars = allBars;
}
public DoSomething() {
// Use _allBars.Bar1
}
}
我能看到的唯一缺点是,这意味着每个类都将通过参数对象注入每个依赖项。从理论上讲,这听起来是个坏主意,但我找不到任何证据表明会引起任何问题。
任何人有任何评论吗?我是否试图通过使我的构造函数代码更简洁来让自己陷入潜在的麻烦?
答案 0 :(得分:3)
您所描述的听起来像service locator pattern,虽然似乎很想通过消除所有这些构造函数参数来简化代码,但从长远来看,通常会损害可维护性。请查看Mark Seemann的帖子Service Locator violates encapsulation,了解有关为什么应避免使用它的更多详细信息。
通常,当您发现自己拥有一个带有数十个构造函数参数的类时,这意味着该类可能承担过多的职责。可以将其分解为目标更狭窄的多个较小的类吗?与其引入一个了解一切的“包罗万象”类,不如说您的应用程序中有一个复杂的部分可以在facade之后进行抽象。
有时候,您最终会得到大型的 coordinator 类,这些类具有许多依赖性,在某些情况下也可以。但是,如果您有很多这样的东西,通常是设计的味道。