c# Dto构造函数和依赖注入

本文关键字:依赖 注入 构造函数 Dto | 更新日期: 2023-09-27 18:14:34

我想知道设计DTO对象的构造函数的最佳实践是什么。

假设我有一个像这样的Dto对象:

class CustomerDto
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Phone { get; set; }
    ...
}

有几种构造对象的方法:

我可以声明一个构造函数:

public CustomerDto(string name, string surname, string phone, ...)
{
    this.Name = name;
    this.Surname = surname;
    this.Phone = phone;
    ...
}

当你看到这个构造函数并立即得出SRP(单一责任)违规的结论时?

尽管这些属性都是相关的

也有人认为没有必要验证属性,因为这是一个DTO,没有行为,行为应该在这个映射的域对象上。

在c#中,我们还可以更优雅地构造这个对象:

var dto = new CustomerDto ()
{
    Name = "Some name",
    Surname = "Some surname"
}

或者使用一个流畅的构建器或框架,如NBuilder。

还使用自动映射框架,如Automapper。使用Ioc容器的问题还在于,变量变得复杂,以及交换参数的风险,例如,您在姓氏中传递了名称,反之亦然,验证可能会错过这比上面的显式映射更容易。

c# Dto构造函数和依赖注入

示例中的值类型不是依赖项。依赖项为使用者提供功能(或配置)。在您的情况下,它们只是分配给DTO的正常值。只要数据属于一起,即使在构造函数中分配了很多值,也不会违反SRP。在这种情况下,唯一的职责是保存数据。

DTO也不应该由IoC容器创建,并且没有真正的依赖关系。您应该手动创建它们,通过您的持久性框架或使用自动映射。

使用构造函数或属性赋值是否更好取决于用法。如果它们是必需的,则构造函数变体更好。

我建议使用不可变数据结构,这样DTO实体就不会暴露任何setter,显然,这样构造函数应该提供初始化给定DTO的所有底层属性的能力。

所以我更喜欢:

public CustomerDto(string name, string surname, string phone, ...) 

DTO是一个数据传输对象,特别用于表示要跨系统(以及分布式)边界传递的一组属性,因此不要过多地担心SRP违反。这类似于Facade设计模式,它抽象了一组操作/服务以简化使用。在这种情况下,Keep It Simple赢了。