跨平台应用程序 WPF、ASP.NET、Silverlight、WP7、XAML

6

考虑到所有应用程序都将与使用云端或 Web 服务的 Web 项目进行交互...

有没有办法在应用程序之间共享我的类模型?

如果有,最好的方法是什么?

关于从 Web 服务发送/接收数据,序列化和反序列化,如何简单地完成此操作而不必手动填充对象?

有关这些应用程序的任何信息都将非常有帮助!

6个回答

6
一般来说,像这样在应用程序之间共享域模型并不是一个好主意,因为这会创建它们之间的硬依赖关系,即对域模型的任何更改都将影响所有应用程序,迫使您同步发布Web、手机和桌面应用程序。
我建议创建针对每种应用程序类型的特定信息需求的单独模型,当然这会增加复杂性,但根据我的经验,这是可以管理的,相比另一种情况而言。
关于序列化问题,如果您使用WCF调用服务,则不是问题,它会为您处理。
对于填充域类,我建议使用AutoMapper,在几个项目中我已经成功地使用了它。它可以基于名称自动映射一个类到另一个类,并且您只需要指定异常(即字段名称不匹配或需要某种类型的转换逻辑)。 Automapper on github

3
通过简单地引用Common.Domain.dll,您可以在WPF和ASP.net之间共享所有类型。然后,您可以通过WCF客户端和服务器共享这些相同的类型(请参见在线示例,例如http://blog.walteralmeida.com/2010/08/wcf-tips-and-tricks-share-types-between-server-and-client.html),从而使分离的应用程序域进行通信。最难的是在Silverlight中共享这些内容,因为据我所知,Silverlight使用了一个精简版的.NET框架和自己的编译器。其中一种技巧是向Common.Domain.dll中定义的C#类添加文件快捷方式,或使用可移植类库(http://msdn.microsoft.com/en-us/library/gg597391.aspx)。但是,所有这些共享是否是一个好主意是一个单独的问题,这取决于您的发布策略。

3

要在多个应用程序之间共享领域模型,请看Microsoft的可移植类库Visual Studio扩展。它包含了创建可以在WPF、Silverlight和Windows Phone上运行的库的模板。生成的编译后的.dll可在所有三个平台上使用。

我曾经使用这种项目类型在WCF服务和其Silverlight消费者之间共享常见的DTO,等等。

要在您的领域模型和DTO之间进行转换,请参考AutoMapper


2
有人建议不要将服务器端的域模型分发给客户端应用程序,而是通过webservice代理生成器生成客户端实体,并使用AutoMap进行映射,但我更喜欢采用通过共享DLL将实体与客户端共享的方法。这有各种优点:
优点:
- 没有重复编码。 - 不需要将映射代理对象转换为真实对象。因此没有性能损失。 - 不需要在服务器和客户端实体上实现双重验证。 - 共享引用实体对象的实用程序库。你不必为客户端代理生成的实体再次编写实用程序库,这是一个大问题。 - 一次设计,随处重用。
缺点:
- 实体库必须是纯香草类。不能引用外部库。 - 无法删除或重命名现有属性。
现在我明白了,有一些反对意见认为服务器实体会发生变化并破坏客户端代码。但在实际情况下,如果你拥有客户端和服务器,你总是可以向客户端发布新版本。即使你不这样做,你也可以对实体的更改进行版本控制,并引入发送新版本实体的新服务。同时,兼容性破坏的可能性很小。只有在删除属性或更改现有实体的属性名称时才会破坏。这通常是低概率事件。在我的经验中,大多数情况下都是向实体添加新属性。即使你向你的实体添加新属性,你旧的客户端仍然可以工作。它仍然可以反序列化SOAP负载。
因此,尽管有一些缺点,但我认为优点大于缺点。所以,我总是有一个包含所有实体的POCO实体DLL,并与客户端应用程序和服务器共享它。
希望这能帮到你。

1

我知道有几个选项。

  1. 在您的 Web 服务中定义模型,当您的应用程序添加对服务的引用时,您还将获得模型定义。

  2. 使用文件链接,将您的域文件链接到每个项目(我们目前使用一些魔法来处理客户端和完整 .net 之间的差异(使用自动映射器或反射来填充本地对象)

  3. 将您的域模型放在一个单独的项目中,并由每个项目引用


我其实已经忘记了这个功能。我会测试一下看看结果如何。但这仍然无法解决序列化的问题。 - J. Lennon

0

我建议创建一个非常精简的Domain项目,它可以完成大部分繁重的工作,但仍然为您的项目类型(WPF、ASP.Net等)提供一个公共层。

由于Domain旨在与所有不同类型的项目一起使用,因此它不能包含在所有所需项目类型中都不可用的命名空间,这将很困难。

为了解决这个问题,我建议创建一个Services项目,通过编译器指令或Services可以是每种项目类型的不同项目的命名空间,来提供您的Domain项目的扩展功能。(这样当只发布Silverlight时,您将发布Services.Silverlight以及Domain和您的Silverlight项目。)这将减少编译器指令的数量。

在拥有上述项目之后,您可以开始为所有其他项目创建前端和应用程序特定逻辑。然后,您可以使用自动映射程序或其他工具将您的(可能的)视图模型映射到Domain中的模型。

拥有DomainServices成为所有核心逻辑的一层将帮助您以后扩展到其他项目类型(如果需要)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接