11: Deploying Prism Applications
To successfully move a Prism application into production, you need to plan for deployment as part of the design process of your application. This chapter covers the considerations and actions you need to perform to prepare your application for deployment and the actions you need to take to get the application in the user's hands.
Silverlight and Windows Presentation Foundation (WPF) have two very different hosting environments, so the deployment considerations are different, depending on whether you are building a Silverlight Prism application or a WPF Prism application.
Deploying Silverlight Prism Applications
Silverlight applications are delivered as XAP files via an HTTP request from a browser. A XAP file is really just a .zip file with a different file name extension and certain expectations about its content. A XAP file contains a set of application assemblies, an application manifest XAML file that describes the package, and possibly additional resource files that the application uses. The XAP file is downloaded by the Silverlight plug-in hosted in a web page. After the Silverlight plug-in is downloaded, it activates the application and runs it within the context of a web page.
Even if you plan to run your Silverlight application Out-Of-Browser (OOB), the user will first need to access the application with the browser via its hosting page; after that, the user can then optionally install the application for OOB use. As a result, the deployment of a Silverlight Prism application is mostly a matter of getting your XAP files in the right place on a web server so the hosting page can download and run them.
Packaging Prism Modules as XAP Files
As discussed in Chapter 4, "Modular Application Development," you can package your modules in multiple ways, including having multiple modules in a single XAP file or having a single XAP file act as a container for a single module. The decision should be determined by whether multiple modules need to be downloaded at the same time because of dependencies between them or the use cases of the application, or whether the modules are logically independent and decoupled in lifetime. Packaging each module in its own XAP file can be a little cleaner from a maintenance and deployment perspective, because each module XAP file becomes a separate unit of deployment that can be versioned independently and added or removed from the application through a simple change to the module catalog.
As an example, consider the architecture of the Stock Trader Reference Implementation (Stock Trader RI). It consists of the shell application and four modules: position, watch, market, and news. Because the application was designed for all those features to "light up" at application start, the modules of the Stock Trader RI are all added statically. The Stock Trader RI shell application project has references to all the module assemblies as class libraries, and the modules are loaded through the ModuleCatalog.AddModule method during application startup in the bootstrapper. In this case, there is only a single XAP that results from the building of the StockTraderRI.Silverlight shell application project, and it contains the shell, the four modules, and the shared infrastructure class library, as shown in the following illustration. If you were deploying the StockTraderRI application, you would simply place that XAP file on your web server and set up the source parameter tag of your Silverlight plug-in object tag in the hosting page to point to that XAP file (typically in a \ClientBin subfolder of your site, using an ASP.NET Web Application hosting project template).
Alternatively, if the modules of the Stock Trader RI were more loosely coupled in terms of when they needed to be loaded, they could have been developed as Silverlight Application projects so they would be built into individual XAP files. If you did that, the deployment architecture would look more like the following illustration. After you break the modules into their own XAP files, you can choose to delay the loading of some of the modules, if appropriate, based on the application functionality. You would typically use a ModuleCatalog.xaml file packaged as part of the shell XAP file to determine what modules the application is composed of, what their dependencies are, and what their loading characteristics are (on-demand or not).
Notice in the following illustration that because the shell and each of the modules has a reference to the infrastructure assembly as a shared class library, if you leave the default settings on those references, you will end up with a separate copy of the library in each of the individual XAP files, which adds unnecessary download size and bandwidth utilization to the application.
|If you plan to have your users install the application OOB, and you expect to deploy updates to your application after it is deployed, you will need to stick to putting all the modules in a single XAP file. The Application.CheckAndDownloadUpdateAsync method will only go out and update the main XAP file that the application was launched from.|
Reducing the Download Size of Your Module XAP Files
To address the duplication of shared class libraries in multiple module XAP files in a Prism application, you have a couple of options. The first is to include the shared library in the shell application XAP file, as it will be by default when you add the reference. Then you go to the reference in each of the modules that also uses the reference and set the Copy Local property on the reference to false. This causes the referenced assembly to not be included in the compiled XAP file for that module. However, at run time, the one provided by the shell application XAP file will also be available to the modules.
The second approach is to leverage application library caching in Silverlight. To use this feature, you go to the Silverlight project properties of a project and select the check box labeled Reduce XAP size by using application library caching. When you do this, any referenced assemblies that have the right metadata files collocated with them will not be included in the XAP file; instead, they will be placed in a separate .zip file, and the .zip file will be referenced by the XAP file's ApplicationManifest.xaml file as an external part. The signed Silverlight Prism Library binaries have the required metadata files to use this feature as well as the libraries from the Silverlight SDK and the Silverlight Toolkit. To leverage this functionality for your own shared assemblies, you need to provide a metadata file, as described in the topic, "How to: Use Application Library Caching" on MSDN.
Preparing Your Web Server to Host Silverlight Applications
Silverlight applications can be hosted on most types of web servers, such as Internet Information Services (IIS) or Apache. However, most web servers are usually configured to serve only a few well-known file name extensions. To allow Silverlight applications to be served from your web server, you have to allow the MIME types in the following table to be served.
Deploying the Application
To deploy a Silverlight application and the modules that are remotely loaded, the XAP files must be made accessible on the web server. There are several ways to accomplish this:
- You can manually copy all the XAP files to a public folder on the web server.
- You can include the Silverlight XAP files in a web project or website and publish from Microsoft Visual Studio. To do this with a Web Application project, the project needs to be part of the same solution as the Silverlight projects that create the XAP files. You then add the Silverlight projects to the Silverlight Applications tab in the web project settings, as shown in the following illustration. A copy of the XAP files from the included Silverlight projects will be placed in a \ClientBin subfolder of the published site. These files are synchronized in the web project each time you build.
Note: To avoid cross-domain call issues, the remote modules' XAP files should be located on the same domain as the main application; when deployed like this, the Ref property on the ModuleCatalog should be a Uniform Resource Identifier (URI) relative to the main XAP file location on the web server.
In addition to publishing or locating the XAP files in the hosting website, the hosting web page will need to refer to the shell application XAP file in its object tag source parameter. Because the hosting page should be part of the same site that the XAP files are placed in for cross-domain reasons, the path specified in the host page should be a relative path.
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> <param name="source" value="ClientBin/ModularityWithUnity.Silverlight.xap"/> ... </object>
Deploying WPF Prism Applications
A WPF Prism application can be composed of an executable and any number of additional DLLs. The main executable is the shell application project. Some of the additional DLLs will be the modules of the application. There may be some additional DLLs that are just shared assemblies used by the shell and modules of the application. In addition, you might have a set of resource or content files that get deployed along with the application.
To deploy a WPF Prism application, you have three choices:
- "XCopy deployment"
- ClickOnce deployment
- Windows Installer deployment
"XCopy deployment" is used as a general term for manual deployment through some sort of file copy operation, which may or may not include the use of the XCOPY command-line tool. If you choose to deploy the application in this way, it is up to you to manually package the files and move them to the target computer. The application should be ready to run as long as the expected folder structure and relative locations of the shell application executable, the module DLLs, and the content files are maintained.
Usually, a more automatic means of deployment is desired to ensure that things get placed in the right location and the user has easy access to run the application. To facilitate that, you can choose to use ClickOnce or Windows Installer (.msi files), depending on what additional installation requirements exist for the application.
The decision of whether to use ClickOnce or Windows Installer is often misunderstood. ClickOnce is not intended to be a one-size-fits-all deployment technology. It is intended for applications that need a low-impact install on a client computer. If your application needs to make computer-wide changes when it is installed—such as to install drivers, integrate with other applications, install services and other things that go outside the scope of just running your executable, ClickOnce is probably not an appropriate deployment choice. However, if you have a lightweight installation on the client computer and you want to benefit from network deployment and update of your WPF application, ClickOnce can be a great choice.
To create a Windows Installer deployment package (.msi file) for your application, you have a variety of choices, including Visual Studio Setup projects, Windows Installer XML (WiX) projects, or numerous third-party installer creation products.
Deploying WPF Prism Application with ClickOnce
ClickOnce is a Windows Presentation Foundation (WPF) or Windows Forms deployment mechanism that has been part of the .NET Framework since version 2.0. ClickOnce enables automatic deployment and update of WPF applications over the network from a deployment server. WPF Prism applications can use ClickOnce to get the shell, modules, and any other dependencies deployed to the client computer. The main challenge with Prism applications is that the Visual Studio publishing process for ClickOnce does not automatically include dynamically loaded modules in the published application.
Deploying a WPF application with ClickOnce is a two-step process. First, you have to publish the application from Visual Studio, and then you can deploy it to client computers. Publishing the application generates two manifests (a deployment manifest and an application manifest), and it copies the application files to a publish directory. That publish folder can then be moved to another server that may not be directly accessible from the developer computer to make the published application accessible to client computers from a known location and URL. Deploying an application to a client computer simply requires providing a URL or link that the user can navigate to. The URL points to the deployment manifest on the publishing deployment server. When that URL is loaded in the browser, ClickOnce on the client computer downloads the manifests and the application files specified by the manifests. After the files are downloaded and stored under the user profile, ClickOnce then launches the application. If subsequent updates are published to the deployment server, ClickOnce can automatically detect those updates, download, and apply them, or there are settings that allow you to detect and apply updates on demand or in the background after the application has launched.
When you publish a WPF Prism application that has dynamically loaded modules, the shell project will typically not have project references to the dynamically loaded modules. As a result, the published ClickOnce application manifest also does not include those module files, and if you deploy the application using ClickOnce, the client computer will not get the module files. To address this, you must modify the application manifest to include the module files that are not referenced by the shell application project.
ClickOnce Publishing Process
You can publish ClickOnce applications from Visual Studio 2010 using a .NET Framework SDK tool named the Manifest Generating and Editing tool (Mage) or a custom tool that uses the ClickOnce publishing APIs. Visual Studio exposes most of the capabilities needed for ClickOnce publishing. However, Visual Studio may not be available or desired for IT administrators who manage ClickOnce deployments on the server. Mage is designed to address most common administrative tasks for ClickOnce; it is a lightweight .NET Framework Windows-based application that can be given to your administrators. However, Mage requires too many detailed steps, performed in the correct order, to successfully complete common tasks such as modifying the application files listed in the application manifest. To make these tasks simpler, a custom utility is needed.
The Manifest Manager Utility sample utility demonstrates how to use the ClickOnce publishing API to manage deployment and application manifests in a simpler way. This utility is used for updating application manifest file lists and deployment manifest settings in a single user interface (UI) and its use is described in later sections in this chapter for initial deployment and update of a Prism application. The Manifest Manager Utility uses APIs exposed in the Microsoft.Build.Tasks.Deployment namespace to load, manipulate, and save modified manifest files for a ClickOnce deployment. You can download the Manifest Manager Utility from the Prism community site on Codeplex at http://compositewpf.codeplex.com/releases/view/14771. To learn the specific steps involved in publishing and updating a WPF Prism application that uses dynamic module loading, see the WPF Prism Deployment Hands-On Lab: Publishing and Updating with ClickOnce.
The following illustration shows the typical structure for a ClickOnce application publication, based on the way Visual Studio generates the deployment folders when you publish an application with ClickOnce. It includes a root folder for the application, which contains the default deployment manifest (.application file). The default deployment manifest usually points to the most recently published version when generated by Visual Studio, but it can be changed to point to whichever version the administrator chooses. The root folder also contains the Setup.exe bootstrapper, which allows you to deploy prerequisites for your application that might require an installer or executable to run before deploying the application using ClickOnce. There is then a subfolder for the application-specific files, under which you get a separate subfolder for each version that you publish. The publish version is a separate project setting and entry in the deployment manifest file for versioning the deployment as a whole, as opposed to the individual assembly versions of the contained assemblies. The publish version is used by ClickOnce to determine when there is an update available from a client that has already installed a ClickOnce application.
Under each publish version's application files folder, you have another copy of the deployment manifest (.application file) that can be used to deploy specific versions to a client computer, or it can be copied to the root folder to cause a server-side rollback to a previous version. The application executable, in addition to any dependent libraries (such as Prism module assemblies) and resource files, will also be in this folder and will be automatically suffixed by a .deploy file name extension when published by Visual Studio. This is done to simplify the file extension mappings on the publishing web server so that you don't have to allow downloads of .dll, .exe, and a myriad of other potential file types that the application is composed of.
The application manifest (.exe.manifest) file is also contained in this folder and is referenced by the deployment manifest. It contains the list of files the application is composed of with hash values per file to assist in change detection; it also contains a list of permissions required by the application to run because ClickOnce can launch applications in a partial trust AppDomain if desired.
If you manually generate or update a ClickOnce application publication using either Mage or a custom tool, you are not constrained to this folder and file structure. For any particular ClickOnce publication, the chain of dependencies includes the following:
- It includes a deployment manifest that points to the application manifest through an embedded code base URL.
- It includes an application manifest that contains relative paths to each of the application files. These files must reside in the same folder or a subfolder from where the application manifest resides.
It includes the application files themselves, usually with a .deploy file name extension appended to the file name to simplify mapping these files to MIME types on the deployment server. ClickOnce automatically strips off the .deploy file name extension on the client side after the file is downloaded.
ClickOnce Deployment and Update Process
The actual deployment of the application to a user via ClickOnce is almost always initiated by providing a URL or hyperlink to the deployment manifest of your published application on the deployment server. The user can click the hyperlink or enter the address in a browser, and the ClickOnce deployment process is invoked. After the manifest and application files are downloaded to the client computer, the application is launched. There are ClickOnce options that allow you to install the application during the initial deployment for offline use, or you can require the user to launch the application using the link or URL every time. When you publish a new version of the application to the deployment server, ClickOnce can automatically or manually check for updates and will download and apply the update for the next time the application launches.
To learn how to use application library caching in Silverlight, see "How to: Use Application Library Caching" on MSDN:
To download the Manifest Manager Utility from the Prism community site on Codeplex at http://compositewpf.codeplex.com/releases/view/14771.
To learn the specific steps involved in publishing and updating a WPF Prism application that uses dynamic module loading, see the WPF Prism Deployment Hands-On Lab: Publishing and Updating with ClickOnce.
Last built: August 28, 2012