我们在WCF Web服务中使用DTO作为数据 Contract . 这些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属性 .
创建方法:用户无法指定Id和CreatedOn属性,因此DTO如下所示:
class CreateOrderData
{
int CreatedBy { get; set; }
string Description { get; set; }
string Name { get; set; }
}
更新方法:用户无法指定Id,CreatedOn和CreatedBy属性,因此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模型中有更多属性,并且很多这些属性在“Create”和“Update”DTO之间共享,那么这些类是否从公共基类扩展是否有意义?如果是,那么“Get”DTO(OrderData)是否也应该从该类扩展?如果我们这样做,是不是让这些DTO过于依赖彼此?
-
如果“创建”和“更新”DTO之间的所有属性都相同,我们是否仍应创建两个不同的DTO?如果是,为什么?如果没有,(现在这只是一个命名问题)应该调用“CreateOrUpdate”DTO,以便名称明显不同于“Get”DTO?
-
是否可以使用“数据”或“数据对象”或“Dto”之类的内容为所有DTO添加后缀?
-
我们在这里走在正确的轨道上吗?如果没有,怎样才能使这种设计更好?
更新:
我认为我不喜欢DTO中的继承,因为基类也将在WSDL中公开,客户端将能够看到它并实例化它对我来说似乎很脏(参见:WCF Serialization with object inheritance?) . 如何在DTO中使用接口来强制执行公共属性而不是继承?由于DTO不应该有任何行为,因此我们不会因为替换继承而损失太多 .
1 回答
由于这是关于个人喜好的很多,我会这样做..
我不会创建一个公共基类,因为它不会在SOLID中遵循L.如果您担心DRY,那么您可以创建聚合 .
如果所有属性都很常见,那么创建一个获取该对象的Save是有意义的,Dto类的顺序将具有一个关键属性,用于指示它是否是现有订单 .
我会用Dto后缀所有,因为很多Dto类名与域类相同,它们会混淆,因为它们将在同一个方法中存在 . 然后你可以用DataContract来装饰你的Dtos(Name =“Order”,Namespace =“htp:// yourdomain / ..”] . 这样他们就会根据你自己的喜好暴露在外面 .
我参与过多个使用相同通用架构的项目,我通常使用AutoMapper将dtos映射到域 . 它对我有用!