我一直在为一个网站重新编写后端,并且已经将其转向三层架构。
我的意图是如此构建:
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 --]
我的问题是:在三层解决方案中共享业务对象是否存在代码气味,或者上面列出的两种方法只是两种不同的方法来破解同一个问题?
答案 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
。
否则,请在服务和翻译器中使用DataContract
将DataContract
转换为UI层中的Model
。 Service Adapter
非常适合 - 它位于UI层,负责使用WCF服务并在DataContract
和Model
之间进行转换。您可以在UI层中使用Service Proxy
,它是WCF服务的包装器,可通过Web使用。
最后,您是否缺少对数据层中Business Objects的引用?我相信您将从数据层本身的数据存储中填充Business Objects。