以下是我们的架构简述:
------------- ---
| UI | | |
------------- | |
| Services | | D |
------------- | T |
| Businsess | | O |
------------- | |
| Dal | | |
------------- ---
我们知道在不同层之间传递数据时,特别是在服务和用户界面之间,应使用DTO类。但是我们对如何使用DTO存在一些概念上的问题(是向UI发送还是从UI接收)。
对于数据驱动项目,我们可以使用POCO自动生成DTO对象。但在大型应用程序中,这并不简单。
我们知道两种解决方案来解决这个问题:
第一种解决方案(除了手动创建的新的DTO之外,同时使用POCO)
例如,假设我们有一个带有许多字段的实体。并且有一个查找组合框,显示实体记录。我们只需要一个实体键作为组合框值字段,另一个字段(例如标题)作为组合框文本字段。因此,我们创建了一个名为“GetAllItemsTitle”的方法来检索所有实体。现在,我们只需返回想要的结构(例如,此示例中的键和值)。因此,我们必须创建一个新的类来存储该结构(一个键和一个值)。
这将是新的DTO类:
[DataContract]
public class SampleManuallyDto
{
[DataMember]
public long Id { get; set; }
[DataMember]
public string Title { get; set; }
}
方法签名如下:
public List<SampleManuallyDto> GetAllItemsTitle()
第二种解决方案(使用可空或Emptyable DTO)
我们可以绕过POCO并手动创建DTO。然后,我们可以将DTO的所有属性定义为可空或类似于可识别为空的东西(我称之为Emptyable)。这使我们可以将DTO用于多个目的。当然,我们需要遵循适配器模式。例如,为那些Emptyable DTO创建两个方法,名为“FromEntity”和“ToEntity”,它将我们手动创建的DTO转换为EntityObjects(Entity Framework的实体对象)。
现在,我们可以绕过“第一种解决方案”(GetAllItemsTitle示例)中创建新DTO类的步骤。
该方法的签名将如下所示:
public List<SampleDTO> GetAllItemsTitle()
但是在方法体中,我们只填充了SampleDTO的"Id"和"Title"属性。正如我所说,SampleDTO的所有属性都可以为空,因此我们只填写需要的部分,其他部分留空。
结论
通常情况下,第一种解决方案(除了手动创建的DTO之外使用POCO)是强类型的。仅需查看方法签名即可找到每个方法返回的数据类型(没有额外的属性)。但是我们担心手动创建的DTO管理问题。它们很快就会增加。
但是第二种解决方案是更加动态的方式,唯一能够识别从“GetAllItemsTitle”返回什么的方法是查看方法体或其文档。因此,我们担心“运行时错误”。开发人员可能认为某个属性不应为空,而实际上却为空。
此外,在我们面临从UI到服务端进行“放置”数据的示例中,我们也遇到了这样的问题。例如,对于更新、插入和其他类似操作,甚至对于“搜索条件”,我们都有相同的选择。
抱歉问题描述得有点长。 请您提供一些有益的建议,谢谢。