views:

947

answers:

3

How to create a WPF application that can be deployed as either a XBAP or as a native Windows application with as little overhead as possible? XBAPs are binary compatible with WPF Windows applications and run on top of the same CLR (Unlike Silverlight). They still differ in some ways.

From deployment point of view their largest difference is that a XBAP has a Page control as the main container while a Windows application has a Window control. It would be rather trivial to make the Windows application use the Page control but I feel (Feel free to disagree) that using a Page navigation method in a Windows application is rather unintuitive.

The second major difference is that XBAPs by default are executed in a partially trusted environment. This can be bypassed though and the XBAPs can be made run in full trust mode. The partial trust mode with XBAPs means you cannot access for example remote web services or native code from the XBAPs directly.

What would be an easy and maintainable way to achieve the following with the above issues?

Requirements

  1. Deployable in both ways: as a XBAP over http and as a stand-alone WPF executable.
  2. Shows information from a remote web server such as flickr or through an unmanaged API.
  3. If possible, the deployment methods should remain faithful to their platforms. That is to say: Use Pages in XBAP where those make sense and dialogs in the Windows app where those make sense.

Restrictions

  1. Platform optimised. The stuff required by the XBAP shouldn't affect the Windows client and vice versa.
  2. The deployment options share as much code as possible. This helps in testing and maintenance.
  3. Running the XBAP should be as simple as possible. Certificate prerequirement would defeat the purpose of a XBAP.

What I have gathered is that first requirement requires two separate projects. The second restriction could be worked upon by having a user control project which contains all the UI and is referenced by the two deployment projects. A WCF web service could work around the limitations of XBAPs.

If employing a solution similar to the above lines the first restriction would require some work as the Windows client could do without the WCF service as it's already running in full trust mode. Also the third requirement would need some deployment specific code so all the UI code cannot be in the user control project.

I'd like to know what solutions could be used to resolve these problems. Feel free to ignore the partial solution. It's there mainly to explain the point and to prevent the "Thought of this already" comments. So just to clarify, I'm interested in all solutions to this problem, not just those that abide to the partial solution.

The reason for interest to this is that a solution would mean there's no need to ponder between a WPF Windows app and a XBAP as these both could be created with little more effort and the client could choose whichever suits them best.

+2  A: 

You may want to take a look at Prism (at codeplex) It helps to target Wpf, Xbap and Silverlight with minimum code changes (the amount of extra work depends on your project).

Here's how to use it to create Wpf and Xbap application: Prism and XBap Applications

jarek
Hum. With a quick glance Prism seems to focus on source code level code sharing. This is required between WPF and Silverlight as these two are not binary compatible. I was mainly referring to assembly level code sharing. That was with a quick glance though. Need to have a better look in the morning.
Mikko Rantanen
Ow. And second point I noted. If Prism requires full trust itself, that more or less defeats the ability to use it directly from a XBAP without deploying it beforehand? Again a quick glance. Will have a better look in the morning!
Mikko Rantanen
It doesn't really require full trust.The main idea is that you have two Shell projects (one for Wpf, one for Xbap) that provide entry point for application.All assemblies with business logic/UI are shared.You create interfaces for services and two different concrete implementations depending on context they run in (WCF if Xbap, direct calls if Wpf).On runtime you use Dependency Injection pattern to provide proper services to your application.
jarek
+2  A: 
Eduardo Molteni
A: 

I have tried several approaches to this over the years. The one that has worked best for me is to have have four projects in a single solution:

  • The main project which builds a dll containing business objects, communications, and UI.
  • The test project containing both manual and automated unit tests
  • A tiny .exe project for the Windows application
  • A tiny .xbap project

In the main project there are neither Pages nor Windows, just UserControls and custom controls. There is also a services class for displaying UI. This class is subclassed in the Windows and XBAP projects to change the way things are displayed. In each case the subclass is installed in a static property as the application starts up. All the rest of the code simply references this static property and calls methods on it. These methods perform services which differ between Windows and XBAP applications.

For example, my service class has a "ShowDialog" method that takes a FrameworkElement and shows it in dialog style, either as a Window (for Windows application) or as a Popup on a page (for XBAP).

Using this technique has allowed for approximately 98% code sharing between the Windows application and the XBAP.

My main application also has a client-server interface defined and WCF attributes applied to its data objects. There is a static property used by all code to access the service. This static property is initialized (in the class constructor) to an instance of the concrete implementation class, but the startup code in the XBAP project replaces this with a WCF client, so the XBAP runs client-server and the Windows application is actually making local calls. In each case it is exactly the same object on the server end.

Because I implemented the WCF as an interface, I was able to get away with nothing more than a simple .svc file for the WCF service end of things, and no need for separate code generation or linking in proxy/stub code.

Ray Burns