通过 WCF 服务从域模型公开数据的最佳方法
Best approach to exposing data from domain models thru WCF services
我在核心库中有大量领域模型,其中还包含获取各种模型集的方法。多个 WCF 服务项目引用此库并发布集合,例如
GetProducts(int categoryId)
我最初的方法是用 DataContract 和 DataMember 属性修饰域模型,return 它们来自 WCF 服务方法。但是我看到了这种方法的缺陷,因为现在一些服务需要将不同的模型属性序列化到其他服务。
我想我有两个选择:
在每个 WCF 项目中创建 DTO 类,其中包含该项目的必要属性和属性,并 return 这些来自服务方法。从领域模型构建 DTO。
这看起来像 "right" 方法,但随着领域模型的扩展,设置和维护非常耗时。
编写我自己的 xml 序列化程序,根据项目动态选择域模型的哪些属性在运行时序列化。我不知道这是否可能!
(我也考虑过 "trick" 将我不想序列化的属性设置为它们的默认值,然后在序列化后将它们改回原来的值,但它太繁琐而且味道不好)
是否有任何其他方法或有什么方法可以减少#1 中涉及的手动工作?
在正确的方法中使用 #1。设计 DTO 以满足客户的要求,并确保它与 WCF 一起正常工作。
从域对象到 DTO 的映射可以通过使用对象到对象映射器大大简化。 AutoMapper 是 .NET 项目中的常见选择.灵活,性能好。
有一个 2b 变体。如果您使用 [DataContract] 标记对象并使用 [DataMember] 属性标记属性,则只有那些将被序列化。
我使用这种方法取得了一些成功。真正的问题是它是否始终与您要序列化的属性相同。例如,如果您有权访问地址对象,那么地址 class 中的所有内容都是公开可见的,这是可行的。即使您在内部为您不公开的某些距离算法保留了一组地理坐标。
但是,如果有些人这样做,而有些人无法访问客户的完整信用卡号,那么如果您尝试对客户进行序列化,这种方法就会出现问题。 (如果地址是一个单独的对象,仍然可以单独确定对客户地址的访问)。
从 ddd 的角度来看可能不是最好的例子,因为地址可能不是一个实体,但我希望你理解我的考虑
我在核心库中有大量领域模型,其中还包含获取各种模型集的方法。多个 WCF 服务项目引用此库并发布集合,例如
GetProducts(int categoryId)
我最初的方法是用 DataContract 和 DataMember 属性修饰域模型,return 它们来自 WCF 服务方法。但是我看到了这种方法的缺陷,因为现在一些服务需要将不同的模型属性序列化到其他服务。
我想我有两个选择:
在每个 WCF 项目中创建 DTO 类,其中包含该项目的必要属性和属性,并 return 这些来自服务方法。从领域模型构建 DTO。 这看起来像 "right" 方法,但随着领域模型的扩展,设置和维护非常耗时。
编写我自己的 xml 序列化程序,根据项目动态选择域模型的哪些属性在运行时序列化。我不知道这是否可能!
(我也考虑过 "trick" 将我不想序列化的属性设置为它们的默认值,然后在序列化后将它们改回原来的值,但它太繁琐而且味道不好)
是否有任何其他方法或有什么方法可以减少#1 中涉及的手动工作?
在正确的方法中使用 #1。设计 DTO 以满足客户的要求,并确保它与 WCF 一起正常工作。
从域对象到 DTO 的映射可以通过使用对象到对象映射器大大简化。 AutoMapper 是 .NET 项目中的常见选择.灵活,性能好。
有一个 2b 变体。如果您使用 [DataContract] 标记对象并使用 [DataMember] 属性标记属性,则只有那些将被序列化。
我使用这种方法取得了一些成功。真正的问题是它是否始终与您要序列化的属性相同。例如,如果您有权访问地址对象,那么地址 class 中的所有内容都是公开可见的,这是可行的。即使您在内部为您不公开的某些距离算法保留了一组地理坐标。
但是,如果有些人这样做,而有些人无法访问客户的完整信用卡号,那么如果您尝试对客户进行序列化,这种方法就会出现问题。 (如果地址是一个单独的对象,仍然可以单独确定对客户地址的访问)。
从 ddd 的角度来看可能不是最好的例子,因为地址可能不是一个实体,但我希望你理解我的考虑