Dynamic loading of additional XAP files

On Silverlight, the DevForce Application Framework provides the means to dynamically load additional XAP files. All MEF Exports found in the assemblies contained in the XAP file will be added to the MEF container and can subsequently be used in the application. MEF together with dynamic XAP loading is a powerful tool to build applications that compose themselves from dynamically loaded parts.

CompositionCatalogService

The CompositionCatalogService provides the necessary support for dynamically loading XAP files through the AddXap() method. The CompositionCatalogService itself can be constructor-injected wherever its services are needed.

The following example demonstrates dynamically loading a ViewModel from a secondary XAP file upon receiving a message from the Caliburn Micro Event Aggregator. Notice that loading a XAP file is an asynchronous operation. In this example we are using a Coroutine to wait for the loading operation to complete before we continue looking for the newly available OrderEditor ViewModel.

[Export(typeof(IMessageProcessor))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class EditOrderMessageProcessor : IMessageProcessor, IHandle<EditOrderMessage>
{
    private readonly IEventAggregator _eventAggregator;
    private readonly ICompositionCatalogService _catalogService;

    [ImportingConstructor]
    public EditOrderMessageProcessor(IEventAggregator eventAggregator, ICompositionCatalogService catalogService)
    {
        _eventAggregator = eventAggregator;
        _eventAggregator.Subscribe(this);

        _catalogService = catalogService;
    }

    public void Handle(EditOrderMessage message)
    {
        IdeaBlade.EntityModel.Coroutine.Start(() => ShowOrderDetail(message));
    }

    /// <summary>
    /// OrderEditorFactory is not available until the xap file gets loaded. AllowDefault=true,
    /// makes sure we don't fail if MEF can't find the OrderEditor. 
    /// AllowRecomposition=true, will tell MEF to set the OrderEditorFactory as
    /// soon as it is available after loading the xap.
    /// </summary>
    [Import("OrderEditor", AllowRecomposition = true, AllowDefault = true)]
    public ExportFactory<object> OrderEditorFactory { get; set; }

    private IEnumerable<INotifyCompleted> ShowOrderDetail(EditOrderMessage message)
    {
        // Let's make sure the xap that contains the OrderEditor is loaded. 
        // Only the first call will load the xap, subsequent calls don't do anything.
        yield return _catalogService.AddXap("HelloWorld.Module.xap");

        // Now we can access the OrderEditorFactory. MEF recomposed this instance
        // and provided us with an OrderEditorFactory. 
        var editor = OrderEditorFactory.CreateExport().Value;
        var handler = editor as IHandle<EditOrderMessage>;
        if (handler != null)
            handler.Handle(message);
    }
}

Last edited Oct 23, 2011 at 6:44 AM by marcelgood, version 6

Comments

No comments yet.