In Silverlight, Cocktail provides the means to dynamically load 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. In addition, any XAP file can contain additional DevForce models that will also be available for use after the loading completes.
The static Composition class provides the necessary support for dynamically loading XAP files through the AddXapAsync() method.
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.
C# | [Export(typeof(IMessageProcessor))] [PartCreationPolicy(CreationPolicy.Shared)] public class EditOrderMessageProcessor : IMessageProcessor, IHandle<EditOrderMessage> { public EditOrderMessageProcessor() { EventFns.Subscribe(this); } 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 Composition.AddXapAsync("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); } } |