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

时间:2011-11-15 11:49:34

标签: c# design-patterns dependency-injection

我想知道设计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容器,ctor变得复杂,以及交换参数的风险,例如,你传递姓氏在哪里,反之亦然,验证可能会错过这个更容易然后如上所述的显式映射。

请帮助说服我哪种方式更好。

2 个答案:

答案 0 :(得分:12)

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

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

如果使用构造函数或属性分配值更好取决于用法。如果需要它们,构造函数变体更好。如果它们是可选的,那么物业方式会更好。

答案 1 :(得分:5)

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

所以我更喜欢:

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

DTO是一个数据传输对象,尤其用于表示要在系统(分布式)边界上传递的一组属性,因此不要过多关注SRP违规。 这就像Facade设计模式,它取消了一组操作/服务以简化使用。所以在这个kase Keep It Simple赢了。