DTO命名约定,建模和继承

Sen*_*nin 32 c# nhibernate dto

我们正在使用AngularJS,C#,ASP.Net Web API和Fluent NHibernate构建Web应用程序.我们决定使用DTO将数据传输到表示层(角度视图).我对DTO的一般结构和命名有些怀疑.这是一个例子来说明我的场景.假设我有一个名为Customer的域名实体,它看起来像:

public class Customer
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual Address Address { get; set; }
        public virtual ICollection<Account> Accounts { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

现在,在我的视图/表示层中,我需要检索不同类型的Customer,如:

1)Id Id和Name 2)Id,Name和Address 3)Id,Name,Address和Accounts

我创建了一组DTO来实现这个目标:

public class CustomerEntry
{
    public  int Id { get; set; }
    public  string Name { get; set; }
}

public class CustomerWithAddress : CustomerEntry
{
    public AddressDetails Address { get; set; }
}

public class CustomerWithAddressAndAccounts : CustomerWithAddress
{
    public ICollection<AccountDetails> Accounts { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

AddressDetails和AccountDetails是DTO,它们具有相应Domain实体的所有属性.

这适用于查询和数据检索; 问题是我将如何使用插入和更新.在创建新客户记录期间,名称和地址是强制性的,帐户是可选的.换句话说,我需要一个具有所有客户属性的对象.因此混淆:

1)我如何使用插入和更新?CustomerWithAddressAndAccounts DTO包含其中的所有内容,但其名称似乎有点难以用于插入/更新.

2)我是否创建了另一个DTO ..如果我这样做,那不会重复,因为新的DTO将完全像CustomerWithAddressAndAccounts吗?

3)最后但并非最不重要的是,上面描述的DTO继承结构是否适合要求?有没有其他方法来模拟这个?

我已就这个主题发表过其他帖子,但未能取得多大进展.我拾取的一件事是避免在类名中使用后缀"DTO".我认为这感觉有点多余.

很想听听你的想法

谢谢

VS1*_*VS1 13

建议是,你应该只需要为每个实体一个DTO类与DTO后缀例如CustomerEntryDTOCustomer entity(但你肯定可以使用继承层次按选择和要求).

而且,添加一种抽象DTOBase类的基类或接口; 并且不要在每个地址,帐户和其他属性中使用这种深度继承的heirarchies包含在子DTO中.相反,将这些属性包含在同一个CustomerEntryDTO类中(如果可能),如下所示:

[Serializable]
public class CustomerEntryDTO : DTOBase, IAddressDetails, IAccountDetails
{
    public  int Id { get; set; }
    public  string Name { get; set; }
    public AddressDetails Address { get; set; } //Can remain null for some Customers
    public ICollection<AccountDetails> Accounts { get; set; } //Can remain null for some Customemer
}
Run Code Online (Sandbox Code Playgroud)

此外,您的DTO 应该是可序列化的,以跨越流程边界.

有关DTO模式的更多信息,请参阅以下文章:

数据传输对象

MSDN

编辑: 如果您不想通过网络发送某些属性(我知道您需要有条件地进行此操作,因此需要对此进行更多探索),您可以使用诸如NonSerialized(但是)之类的属性将它们排除在序列化机制之外它仅适用于字段而非属性,请参阅与属性一起使用的变通方法文章:属性上的NonSerialized).您还可以创建自己的自定义属性,例如,ExcludeFromSerializationAttribute并根据某些规则/条件将其应用于您不希望每次都通过网络发送的属性.另请参阅: 条件xml序列化

编辑2: 使用接口分隔一个CustomerEntryDTO类中的不同属性.请参阅Google或MSDN上的界面分离原则.我稍后会尝试做一个示例解释.

  • 在.NET世界中,使用DTO为您的类添加后缀是愚蠢的,只需指出.我们倾向于使用Entities作为存储库对象和Model从API返回的对象,对于服务对象,他们通常不使用任何前缀.公平地说,所有这些层都使用DTO,所以我们应该开始命名实体XptoDtoEntities吗?!放弃DTO命名它很难看. (3认同)
  • 我只是引用你的话并证明你是错的。讨论完毕。 (3认同)
  • 很好的答复,但我认为不需要在DTO上应用接口。这有什么用?对于具有实际逻辑的对象,而不是简单的数据结构,ISP与其他SOLID很好结合使用。 (2认同)
  • @Marco后缀在将视图模型映射到实体时很有用,并且在此过程中导入两层的类时,您不希望名称冲突。 (2认同)