如何组织和命名在WCF Web服务中用作数据合同的DTO?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (15)

我们在我们的WCF Web服务中使用DTO作为数据合同。这些DTO的目的是仅公开与特定API方法相关的信息。

我向你们寻求的是一些关于这里最佳实践的建议。

例如,考虑以下简单模型:

class Order
{
    int CreatedBy { get; set; }
    DateTime CreatedOn { get; set; }
    string Description { get; set; }
    int Id { get; set; }
    string Name { get; set; }
}

假设我们的API允许消费者创建更新获取订单,我们创建了以下DTO。为简单起见,DataMember和DataContract属性被删除。

用户不能指定IdCreatedOn属性,所以DTO看起来像这样:

class CreateOrderData
{
    int CreatedBy { get; set; }
    string Description { get; set; }
    string Name { get; set; }
}

用户不能指定IdCreatedOnCreatedBy属性,所以DTO看起来像这样:

class UpdateOrderData
{
    string Description { get; set; }
    string Name { get; set; }
}

获取方法:用户应该能够看到订单的所有内容,所以DTO看起来像这样:

class OrderData
{
    int CreatedBy { get; set; }
    DateTime CreatedOn { get; set; }
    string Description { get; set; }
    int Id { get; set; }
    string Name { get; set; }
}

所以这里是我的问题:

  • 假设Order模型中有更多属性,并且这些属性中的很多属性在“创建”和“更新”DTO之间共享,那么让这些类从共同基类中扩展是否有意义?如果是的话,那么“Get”DTO(OrderData)是否也可以从该类扩展?如果我们这样做,是否不会让这些DTO过于依赖对方?
  • 如果所有的属性在“创建”和“更新”DTO之间是常见的,我们是否应该创建两个不同的DTO?如果是,为什么?如果没有,(现在只是一个命名问题)应该调用“CreateOrUpdate”DTO,以便名称明显不同于“Get”DTO?
  • 可以用“Data”或“DataObject”或“Dto”之类的后缀来附加所有的DTO吗?
  • 我们在这里是否正确?如果没有,如何才能使这个设计更好?

我想我不喜欢DTO中的继承,因为基类也将暴露在WSDL中,并且客户端将能够看到它并实例化它,这对我来说似乎很脏。如何使用DTO中的接口强制执行通用属性而不是继承?由于DTO不应该在其中产生任何行为,因此我们不会因为替换继承而损失太多。

提问于
用户回答回答于

由于这是个人偏好很多,我会这样做..

  1. 我不会创建一个通用的基类,因为它不符合SOLID中的L. 如果您担心DRY,那么可以创建一个聚合。
  2. 如果所有属性都是常见的,那么创建一个接受该对象的Save是有意义的,那么Dto类的订单将具有一个关键属性(ies),该关键属性将指示其是否存在现有订单。
  3. 我将后缀全部为Dto,因为很多Dto类名与域类相同,所以它们会混淆,因为它们将以相同的方法存在。然后你可以用DataContract(Name =“Order”,Namespace =“htp:// yourdomain / ..”]来修饰你的Dtos,这样他们就会根据自己的喜好被暴露给外部世界。

我一直在使用相同的一般体系结构的多个项目中,我通常使用AutoMapper将dtos映射到域。它对我很好!

扫码关注云+社区