我们正在使用EF,WCF和jQuery实现SOA Web应用程序。
以下是我们的架构简介:
------------- ---
| UI | | |
------------- | |
| Services | | D |
------------- | T |
| Businsess | | O |
------------- | |
| Dal | | |
------------- ---
我们知道我们应该让DTO类在服务和UI之间专门在层之间传递数据但我们在使用DTO的方式(发送到UI或从UI接收)方面存在一些概念性问题。
对于数据驱动项目,我们可以使用POCO自动生成DTO对象。但在大型应用程序中,并不是那么简单。
我们知道两种解决方案来解决我们的问题:
第一个解决方案(除了新手动创建的DTO之外还使用POCO)
例如,假设我们有一个包含许多字段的实体。并且有一个查找组合框,显示实体记录。我们只需要一个实体键作为组合框值字段,另一个字段(例如Title)作为组合框文本字段。因此,我们创建一个名为“GetAllItemsTitle”的方法来检索所有实体。现在我们应该返回我们想要的结构(本例中的一个键和一个值)。所以我们必须创建一个新类来存储该结构(一个键和一个值)。
这将是新的DTO课程:
[DataContract]
public class SampleManuallyDto
{
[DataMember]
public long Id { get; set; }
[DataMember]
public string Title { get; set; }
}
方法签名是这样的:
public List<SampleManuallyDto> GetAllItemsTitle()
第二种解决方案(使用Nullable或Emptyable DTO)
我们可以绕过POCO并手动创建DTO。然后我们可以将DTO的所有属性定义为可空或类似可以被识别为空的属性(我称之为Emptyable)。它允许我们将DTO用于多种目的。当然,我们需要遵循适配器模式。例如,为名为“FromEntity”和“ToEntity”的可清空DTO创建两个方法,将我们手动创建的DTO转换为EntityObjects(实体框架)。
现在我们可以在“第一个解决方案”(GetAllItemsTitle)的示例中绕过创建新的DTO类。
方法签名将如下:
public List<SampleDTO> GetAllItemsTitle()
但是在方法体中我们只填充SampleDTO的“Id”和“Title”属性。正如我所说,SampleDTO的所有属性都可以为空,所以我们只填充我们想要的那些并将其他属性留空。
结论
通常,第一种解决方案(除了新手动创建的DTO之外使用POCO)是强类型的。只需查看方法签名(没有额外的属性)就可以找到每个方法的返回数据类型。但我们担心管理手动创建的DTO。他们很快就会长大。
但是第二种解决方案是一种更加动态的方式,识别将从“GetAllItemsTitle”返回的内容的唯一方法是查看方法体或其文档。所以我们担心“运行时错误”。开发人员可能会认为属性在空时不应为空。
更重要的是,当我们将数据从“UI”变为“服务”时,我们遇到了这样的问题。例如,对于Update和Insert以及其他此类操作。即使是“搜索标准”,我们也有相同的选择。
很抱歉这个问题很长。 请帮助我们提出您的意见。
答案 0 :(得分:2)
忘掉数据层的一切。创建适用于每个特定Web服务调用的DTO:s。
如何构建DTO或如何使用DTO并不重要。唯一重要的是如何将它们设计为最小化每个操作的Web服务调用量。
例如:假设您有一个用例,您需要遍历所有用户以修改其地址。如果您首先需要获取所有用户,然后为每个用户进行Web服务调用以获取其地址,那么设计就会很糟糕。正确的设计是在一次通话中返回UserWithAddress
DTO:s的列表。
答案 1 :(得分:1)
那么我们如何管理大型项目的大量DTO?你的意思是我们应该为UserInfo的每个组合都有一个DTO,例如UserWithAddress,UserWithAddressAndAge,UserWithAge,UserWithPhoneNumber,UserWithBlahBlahBlah?这将是大型域中的混乱,难以管理和维护。我真的更喜欢Nullable DTO。 对于从现实世界映射的每个对象,您应该有一个Dto。这是指定应如何使用的业务职责。一旦你创建了Dto,然后根据你的业务使用它。调用GetUserAddress服务,不要指望UserAge或任何其他东西。当我们在设计中将用户映射到面向对象的用户时,有一个DTO供用户使用。
还有一件事!如果我们为每个单一目的和数据服务组合创建一个Dto,作为最近加入支持团队的开发人员,我如何为我的新方法找到所需的Dto?我应该搜索所有Dtos并小心我的正确选择(如果我是一个懒惰和粗心的开发人员会怎么样?)也许我应该读一本像“项目的DTOS”的文档书。熟悉可用的DTO。
答案 2 :(得分:1)
DTO应根据需要映射到请求或能力。您可以聚合各种基础数据实体并返回合成或类似外观的DTO,或者您可能返回仅代表单个数据实体的一小部分的贫血DTO。在做出此决策时,您希望平衡有效负载,粒度和其他SOA问题。