Anyone who has written an application with complexity enough to warrant multiple controls on multiple pages/forms should understand the benefit of composite application development. That is defining your application architecture that can be separated into separate pieces each with it’s own distinct purpose that can then be “composed” together into the solution.
Composition can be useful in any layer of the application, from the presentation layer, the business layer, common services or data access. Historically people have had different options to achieve composing applications from distinct well known pieces – their own version of dependency injection, containers to aid with composition like Unity, the composite application guidance for WPF and Silverlight and before that the composite application block.
Microsoft has been working on another mechanism to aid composition and extension of applications for some time now – the Managed Extensibility Framework or MEF for short. With Silverlight 4 it is part of the Silverlight environment. MEF allows a much simplified mechanism for composition and extensibility compared to other mechanisms – which has always been the primary issue for adoption of the earlier mechanisms/frameworks.
This post will guide you through the simple use of MEF for the scenario of composition of an application – using exports, imports and composition.
Steps:
1. Create a new Silverlight 4 application.
2. Add references to the following assemblies:
System.ComponentModel.Composition.dll
System.ComponentModel.Composition.Initialization.dll
3. Add a new user control called LeftControl.
4. Replace the LayoutRoot Grid with the following xaml:
<Grid x:Name="LayoutRoot" Background="Beige" Margin="40" >
<Button Content="Left Content" Margin="30"></Button>
</Grid>
5. Add the following statement to the top of the LeftControl.xaml.cs file
using System.ComponentModel.Composition;
6. Add the following attribute to the LeftControl class
[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.
7. Add a new user control called RightControl.
8. Replace the LayoutRoot Grid with the following xaml:
<Grid x:Name="LayoutRoot" Background="Green" Margin="40" >
<TextBlock Margin="40" Foreground="White" Text="Right Control" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Center" ></TextBlock>
</Grid>
9. Add the following statement to the top of the RightControl.xaml.cs file
using System.ComponentModel.Composition;
10. Add the following attribute to the RightControl class
[Export(typeof(RightControl))]
11. Add the following xaml to the LayoutRoot Grid in MainPage.xaml:
<StackPanel 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 imported and composed via MEF.
12. Add the following statement to the top of the MainPage.xaml.cs file
using System.ComponentModel.Composition;
13. Add the following properties to the MainPage class:
[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.
14. Replace the MainPage constructore with the following code:
public MainPage()
{
InitializeComponent();
CompositionInitializer.SatisfyImports(this);
LeftContent.Child = LeftUserControl;
RightContent.Child = RightUserControl;
}
The CompositionInitializer.SatisfyImports(this) function call tells MEF to discover types related to the declared imports for this object (the MainPage object). At that point, types matching those specified in the import defintions are discovered in the executing assembly location of the application and instantiated and assigned to the matching properties of the current object.
15. Run the application and you will see the left control and right control types displayed in the MainPage:
Congratulations! You have used MEF to dynamically compose user controls into a parent control in a composite application model.
In the next post we will build on this topic to cover using MEF to compose Silverlight applications dynamically in download on demand scenarios – so .xap packages can be downloaded only when needed, avoiding large initial download for the main application xap.
Take the Slalom Challenge at www.slalomchallenge.com!