c# - 构造函数过度注入(inject)类型专注于收集数据

标签 c# dependency-injection constructor

我知道这个论点在 S.O. 上有很好的阐述,尤其是在

Why not use an IoC container to resolve dependencies for entities/business objects?

还有其他问题;但疑虑依然存在。

我使用了收集数据的类型而不是实体业务对象来使问题集中在原则上。 p>

所以,如果我有这样一个依赖于 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
}

这是构造函数过度注入(inject)的情况吗?

Mark Seemann建议本书将依赖项的数量保持在 2 到 4 个之间(如果我没记错的话)。

对于这种反模式可能不适用的类型吗?

最佳答案

这些并不是通常意义上的真正依赖 - 它们是实体的数据。它不像那些东西提供多态服务等。我通常不会期望依赖注入(inject)框架(或 IoC 容器)来创建这样的对象 - 通常它会是 ORM 或 hand 的一部分-编写代码。

调用这样的构造函数确实有点麻烦,如果你想提供默认值也变得很棘手。不过,如果您使用的是 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);

关于c# - 构造函数过度注入(inject)类型专注于收集数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15541169/

相关文章:

c# - 数据包格式不正确,使用 WSDL 文件从 C# 调用 SAP 服务

c# - 基于声明的表单例份验证角色

asp.net-mvc - 无法获得有效的 Unity session 生命周期管理器,ASP.NET MVC5

dependency-injection - 为什么我不能在 Managed Bean 构造函数中使用 Init 属性?

java - 为子类传递构造函数参数时出现"Could not resolve matching constructor"错误

VB.NET设置类属性初始值

c# - HttpContext.Current.Session 给出 StackOverflowException?

c# - 单击 WPF 中的按钮显示用户控件 (WPF) 查看页面

c# - ASP.NET Core Singleton 实例与 Transient 实例性能

c++ - 稍后在 C++ 中调用基类构造函数(不在初始化列表中)