将DTO / POCO放置在三层项目中

时间:2012-07-17 11:04:07

标签: c# entity-framework poco dto 3-tier

我一直在为一个网站重新编写后端,并且已经将其转向三层架构。

我的意图是如此构建:

Web site <--> WCF Service (1) <--> Business Layer (2) <--> Data Layer (3)

我的问题是在这个结构中放置DTO。我需要使用DTO在业务层和WCF服务之间以及从WCF服务到消费网站之间移动数据。

在我研究这里的过程中,我已经阅读了一些很好的讨论,虽然我一直在摸不着头脑:

  • Davide Piras在this post中提出了一些很好的观点,如果我遵循这个设计,那么我会在一个单独的项目中为POCO声明接口。然后,这些将由层(1)和(2)实现。虽然我喜欢使用接口,但似乎我通过在(1)和(2)中声明POCO然后使用类似AutoMapper之类的来回复制数据来为自己做更多的工作。

  • This post使用一个系统,其中创建了一个业务对象项目,该项目将被所有层引用。这似乎比其他解决方案更简单,似乎引导我找到一个

  • 的解决方案

Web site <--> WCF Service (1) <--> Business Layer (2) <--> Data Layer (3)

^               ^                       ^
|               |                       |
[ -- Business Objects Referenced here --]

^ ^ ^ | | | [ -- Business Objects Referenced here --]

我的问题是:在三层解决方案中共享业务对象是否存在代码气味,或者上面列出的两种方法只是两种不同的方法来破解同一个问题?

2 个答案:

答案 0 :(得分:2)

我会说,这通常取决于您正在构建的项目的复杂性。对于我构建的小型项目,我在各层共享了我的“实体”(它们只是简单的DTO,带有getter和setter的可序列化数据桶),并且对此并不太在意。最大的缺点是逻辑分散在整个项目中(不仅仅是在“业务层”),而且整个过程都采用了程序化的方式。这看起来真的像贫血领域模型,但由于项目没有增长太多,复杂性并没有蔓延。实体框架有一些模板,你可以建立你的实体(如果我没有记错,他们被称为自我追踪实体?)。

对于中型/大型项目,我不会使用这种方法,并且会将实体和DTO分开,因为它们将扮演不同的角色。 DTO可能与您的实体形状完全不同,并且尝试在层/层之间共享它们通常会很臭。

答案 1 :(得分:2)

让我们将您的UI(网站)和服务(WCF + BL + DAL)视为两个不同的实体。

  • 如果您完全控制两者,则应选择方法#2,因为它将避免WCF代理对象与UI层中的业务对象之间的转换。

  • 此外,您最好采用方法#1,因为其中一个实体是一种“黑匣子”,并且可能会受到外部利益相关者的影响。因此,维护一组内部业务对象更安全。这需要在业务对象和WCF代理对象之间进行转换(通过扩展方法或转换器框架)。

现在,不完全确定您的UI层复杂性或其实现(MVC,WebForms等),因此您可能需要或不需要View特定对象(数据绑定更轻,序列化为JSON更快等等。 ),让我们将此对象称为Model

  • 如果您不需要特定的UI特定Model,建议您将业务对象标记为DataContract(在WCF的上下文中)并跨层使用它们。如果您通过网络(Serializable)调用WCF,请不要忘记将实体明确标记为$.ajax

  • 否则,请在服务和翻译器中使用DataContractDataContract转换为UI层中的ModelService Adapter非常适合 - 它位于UI层,负责使用WCF服务并在DataContractModel之间进行转换。您可以在UI层中使用Service Proxy,它是WCF服务的包装器,可通过Web使用。

最后,您是否缺少对数据层中Business Objects的引用?我相信您将从数据层本身的数据存储中填充Business Objects。