2

如何创建一个 WPF 应用程序,该应用程序可以部署为 XBAP 或本地 Windows 应用程序,并且开销尽可能少?XBAP 与 WPF Windows 应用程序二进制兼容,并在相同的 CLR 之上运行(与 Silverlight 不同)。它们在某些方面仍然不同。

从部署的角度来看,它们最大的区别是 XBAP 有一个 Page 控件作为主容器,而 Windows 应用程序有一个 Window 控件。让 Windows 应用程序使用 Page 控件相当简单,但我觉得(尽管不同意)在 Windows 应用程序中使用 Page 导航方法是相当不直观的。

第二个主要区别是默认情况下 XBAP 在部分受信任的环境中执行。不过,这可以绕过,XBAP 可以在完全信任模式下运行。XBAP 的部分信任模式意味着您不能直接从 XBAP 访问远程 Web 服务或本机代码。

对于上述问题,实现以下目标的简单且可维护的方法是什么?

要求

  1. 可通过两种方式部署:作为基于 http 的 XBAP 和作为独立的 WPF 可执行文件。
  2. 显示来自远程 Web 服务器(如 flickr)或通过非托管 API 的信息。
  3. 如果可能,部署方法应该忠实于他们的平台。也就是说:使用 XBAP 中有意义的页面和 Windows 应用程序中有意义的对话框。

限制

  1. 平台优化。XBAP 所需的东西不应影响 Windows 客户端,反之亦然。
  2. 部署选项共享尽可能多的代码。这有助于测试和维护。
  3. 运行 XBAP 应该尽可能简单。证书前置要求会破坏 XBAP 的目的。

我收集到的是第一个要求需要两个单独的项目。第二个限制可以通过拥有一个包含所有 UI 并被两个部署项目引用的用户控件项目来解决。WCF Web 服务可以解决 XBAP 的限制。

如果采用类似于上述行的解决方案,则第一个限制将需要一些工作,因为 Windows 客户端可以在没有 WCF 服务的情况下完成,因为它已经在完全信任模式下运行。第三个要求还需要一些特定于部署的代码,因此所有 UI 代码都不能在用户控件项目中。

我想知道可以使用哪些解决方案来解决这些问题。随意忽略部分解决方案。它主要是为了解释这一点并防止“已经想到这一点”的评论。所以澄清一下,我对这个问题的所有解决方案都感兴趣,而不仅仅是那些遵守部分解决方案的解决方案。

对此感兴趣的原因是,解决方案意味着无需在 WPF Windows 应用程序和 XBAP 之间进行考虑,因为这两者都可以轻松创建,并且客户可以选择最适合他们的那个。

4

3 回答 3

3

这篇 scorbs 文章解释了如何做到这一点,它甚至有一个应用程序模板来做到这一点。

替代文字
(来源:scorbs.com

于 2009-06-12T21:45:40.597 回答
2

您可能想看看 Prism(在 codeplex 上)它有助于以最少的代码更改定位 Wpf、Xbap 和 Silverlight(额外工作量取决于您的项目)。

以下是如何使用它来创建 Wpf 和 Xbap 应用程序:Prism 和 XBap 应用程序

于 2009-05-02T22:42:14.697 回答
0

多年来,我尝试了几种方法。对我来说效果最好的一个是在一个解决方案中包含四个项目:

  • 构建包含业务对象、通信和 UI 的 dll 的主项目。
  • 包含手动和自动单元测试的测试项目
  • 用于 Windows 应用程序的小型 .exe 项目
  • 一个很小的 ​​.xbap 项目

在主项目中既没有 Pages 也没有 Windows,只有 UserControls 和自定义控件。还有一个用于显示 UI 的服务类。此类是 Windows 和 XBAP 项目中的子类,以更改事物的显示方式。在每种情况下,子类都会在应用程序启动时安装在静态属性中。所有其余的代码只是简单地引用这个静态属性并调用它的方法。这些方法执行 Windows 和 XBAP 应用程序之间不同的服务。

例如,我的服务类有一个“ShowDialog”方法,它接受一个 FrameworkElement 并以对话框样式显示它,或者作为窗口(对于 Windows 应用程序)或作为页面上的弹出窗口(对于 XBAP)。

使用这种技术可以在 Windows 应用程序和 XBAP 之间实现大约 98% 的代码共享。

我的主应用程序还定义了一个客户端-服务器接口,并将 WCF 属性应用于其数据对象。所有代码都使用一个静态属性来访问服务。此静态属性被初始化(在类构造函数中)为具体实现类的实例,但 XBAP 项目中的启动代码将其替换为 WCF 客户端,因此 XBAP 运行客户端-服务器,Windows 应用程序实际上是本地来电。在每种情况下,它都是服务器端完全相同的对象。

因为我将 WCF 实现为一个接口,所以我只需要一个用于 WCF 服务端的简单 .svc 文件就可以逃脱,并且不需要单独的代码生成或代理/存根代码中的链接。

于 2010-01-01T09:22:20.900 回答