MEF gives us the ability to do this. This post will cover the basics needed to build such a composite application split between different silerlight applications and download the referenced silverlight application only when needed.
Steps:
System.ComponentModel.Composition.dll
System.ComponentModel.Composition.Initialization.dll
System.ComponentModel.Composition.dll
System.ComponentModel.Composition.Initialization.dll
<Grid x:Name="LayoutRoot" Background="Beige" Margin="40" >
<Button Content="Left Content" Margin="30"></Button>
</Grid>
using System.ComponentModel.Composition;
[Export(typeof(LeftControl))]
This attribute tells MEF that the type LeftControl will be exported – i.e. made available for other applications to import and compose into the application.
<Grid x:Name="LayoutRoot" Background="Green" Margin="40" >
<TextBlock Margin="40" Foreground="White" Text="Right Control" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Center" ></TextBlock>
</Grid>
using System.ComponentModel.Composition;
[Export(typeof(RightControl))]
<Grid.RowDefinitions>
<RowDefinition Height="65*" />
<RowDefinition Height="235*" />
</Grid.RowDefinitions>
<Button Name="LoaderButton" Content="Download External Controls" Click="Button_Click"></Button>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" >
<Border Name="LeftContent" Background="Red" BorderBrush="Gray" CornerRadius="20"></Border>
<Border Name="RightContent" Background="Red" BorderBrush="Gray" CornerRadius="20"></Border>
</StackPanel>
The borders will hold the controls that will be downlaoded, imported and composed via MEF when the button is clicked.
using System.ComponentModel.Composition;
[Import(typeof(LeftControl))]
public LeftControl LeftUserControl { get; set; }
[Import(typeof(RightControl))]
public RightControl RightUserControl { get; set; }
This defines properties accepting LeftControl and RightControl types. The attrributes are used to tell MEF the discovered type that should be applied to the property when composition occurs.
private void Button_Click(object sender, RoutedEventArgs e)
{
DeploymentCatalog deploymentCatalog =
new DeploymentCatalog("ExternalSilverlightApplication.xap");
CompositionHost.Initialize(deploymentCatalog);
deploymentCatalog.DownloadCompleted += (s, i) =>
{
if (i.Error == null)
{
CompositionInitializer.SatisfyImports(this);
LeftContent.Child = LeftUserControl;
RightContent.Child = RightUserControl;
LoaderButton.IsEnabled = false;
}
};
deploymentCatalog.DownloadAsync();
}
This is where the magic happens! The deploymentCatalog object is pointed to the ExternalSilverlightApplication.xap file. It is then associated with the CompositionHost initialization. As the download will be asynchronous, an eventhandler is created for the DownloadCompleted event. The deploymentCatalog object is then told to start the asynchronous download.
The event handler that executes when the download is completed uses the CompositionInitializer.SatisfyImports() function to tell MEF to satisfy the Imports for the current class. It is at this point that the LeftUserControl and RightUserControl properties are initialized with composed objects from the downloaded ExternalSilverlightApplication.xap package.
Congratulations! You have implemented download on demand capabilities for composite applications using the MEF DeploymentCatalog class. You are now able to segment your applications into separate xap file for deployment.