我知道这个论点在S.O.上有很好的涵盖,特别是在
中Why not use an IoC container to resolve dependencies for entities/business objects?
还有其他问题;但怀疑仍然存在。
我使用了收集数据的类型而不是实体或业务对象,以使问题集中在原则上。
所以,如果我这样的类型依赖于这样的primitive data(甚至更多的字段):
public class Animal {
private readonly string name;
private readonly string nickname;
private readonly int weight;
private readonly int heightAtWithers:
private readonly Color mainColor;
private raadonly bool isMale;
private readonly bool isAggressive;
public Animal(string name, string nickname, int weight,
int heightAtWithers, Color mainColor,
bool is Male, bool isAggressive)
{
// remainder omitted
}
public string Name { get { return this.name; } }
// remainder omitted
}
这是构造函数过度注入的情况吗?
在Mark Seemann书中建议保持较低的依赖数,2到4(如果我没有错)。
对于此反模式不适用的此类型是否可能?
答案 0 :(得分:8)
在正常意义上,这些并非真正的依赖 - 它们是实体的数据。它不像那些东西提供多态服务等。我通常不会期望依赖注入框架(或IoC容器)来创建这样的对象 - 通常它将是ORM或手的一部分写代码。
调用这样的构造函数确实有点痛苦,如果你想提供的默认值也变得棘手。如果您使用C#4或更高版本,可选参数和命名参数可以提供帮助。 (它们确实要求在编译时知道默认值,请注意。)
另一种方法是创建一个具有相关默认值的可变构建器类型。我通常把它变成一个嵌套类。您可以为它提供一个无参数构造函数,只需在构建构建器时验证所需的所有内容,或者为构造函数提供所有必需的值,并保留可选值的属性。然后,您可以使用对象初始值设定项来愉快地创建实例:
var animal = new Animal.Builder("Frederick") {
NickName = "Freddie",
Weight = 10,
MainColor = Color.Brown
}).Build();
编写构建器会刺激锅炉板工作,但它可能很有用。如果您发现做在构造实例时始终具有相关信息,那么坚持使用当前的构造函数可能更简单。考虑使用命名参数使每个参数的含义更清晰,特别是当存在多个具有相同类型的参数时:
var animal = new Animal(name: "Frederick", nickname: "Freddie",
weight: 10, heightAtWithers: 20,
Color.Brown, isMale:true, isAggressive: false);
答案 1 :(得分:5)
依赖于很多其他服务的课程很可能不止一件事 对于依赖于大量原语的类来说,情况不一定如此。
话虽如此,原始数据类型的依赖关系和“数据持有者类”的数据是两回事。
将您的课程与您所链接文章中描述的课程进行比较:
DbChartReader
需要 top
才能完成工作 - 这是一种依赖。
Animal
没有做任何工作。通过构造函数传入的数据基本上是 对象 - 构造函数参数就是:data。