Prism gives you two options on how to configure the ModuleCatalog, typically in the BootStrapper, these include programmatically or from a XAML file that is embedded in the XAP file. This is a quick post to shown a very simple example of loading the ModuleCatalog for in an asynchronous fashion. This example will load the ModuleCatalog from an XML file located on the web server. The example will be abstract in implementation, but consider the scenario that you allow Administrators to upload modules into the application. When a new module is installed the catalog needs to be updated so that the Silverlight application will see them the next time it reloads the ModuleCatalog.

 

1. Create a Bootstrapper that inherits from your choice of a BootStrapper base class.

 

public class AsyncBootstrapper

        : MefBootstrapper

Here we are using the MefBootstrapper but there is no reason you could not use Unity or any DI framework that you choose to integrate with Prism.

 

2. Implement the required abstract method CreateShell. Here we return a user control that simply servers as a custom loading / splash screen.

       protected override DependencyObject CreateShell()
        {
            return new LoadingView();
        }

Delaying the creation of the shell may not always be necessary. However, given that Async processes can throw error and do not always complete. It would be nice to have some type of custom view and to handle any exceptions gracefully.

 

3. Override the base class CreateModuleCatalog method and in this method we are going to request the xml file from the server.

        protected override IModuleCatalog CreateModuleCatalog()
        {
            ModuleCatalog catalog = new ModuleCatalog();
            WebClient client = new WebClient();
            client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
            client.OpenReadAsync(new Uri(http://localhost:6639/ModuleCatalog.xml, UriKind.RelativeOrAbsolute), catalog);
            return catalog;
        }

 

To keep this example as simple as possible we are just hard coding a path to an XML file. Imagine pointing this to a REST service that could construct the response from a database possibly event based authorization rules etc. You could also use any other async process in place of this web get request, such as a RIA Services DomainContext or a standard WCF service call.

 

4. In the event handler for the OpenReadCompleted we take the response and load it into the ModuleCatalog and set the RootVisual to the Shell for our application.

        private void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            var catalog = Microsoft.Practices.Prism.Modularity.ModuleCatalog.CreateFromXaml(e.Result);
            foreach (var item in catalog.Modules)
                this.ModuleCatalog.AddModule(item);
            App.Current.RootVisual = this.Container.GetExportedValue<Shell>();
        }

Continuing the comments about step 3, if you were using a different way of requesting the catalog this code could be very different. For example, instead of using the CreateFromXaml method you may enumerate through a collection returned from WCF and programmatically configure the catalog. Also, if you did not use a custom loading page you would not need to set the RootVisual here.

I tried to keep this example short and to the point. However, the simplicity of the example keep you from considering this solution in more complicated scenarios. A complete solution would probably include caching a copy of the catalog in IsolatedStorage and loading from cache if the application is offline. It should be able to be applied in many scenarios that included updating the available modules without redeploying the main XAP file.

As always, I hope this helps and look forward to your feedback!

Last edited Mar 10, 2011 at 6:05 AM by itlackey, version 1

Comments

No comments yet.