Exercise 3: Using MEF and Silverlight 4

Latest version of Silverlight 4 will include MEF out of the box. This means all the functionality described in the previous exercises are available for Silverlight 4 applications.

Some minor tweaks are required because of the different deployment model of a Silverlight application.

In this exercise, you will go through the creation of a Silverlight version of the Cash Maker application reusing most of the code and logic already present in the WPF version of the application.

Task 1 – Convert Extensions to Silverlight

In this task, you will convert all the Class Library projects used by the WPF version of the Cash Maker application to Silverlight. You will reuse all the code present in the WPF version by adding links to the existing files.

  1. Open Microsoft Visual Studio 2010 from Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010.
  2. Open the ContosoAutomotive.sln solution file. By default, this file is located in the folder Source\Ex3\begin(choosing the folder that matches the language of your preference.) Optionally, you can continue working the solution you created in the previous exercise.
  3. Because a Silverlight 4 application can only reference Silverlight Class Libraries, you will replicate all the extension and contract definitions for Silverlight 4. You will start adding the Silverlight 4 version of Contoso.Automotive.Common library. To do this, right click on the ContosoAutomotive solution node and select Add | New Project. In the Add New Project dialog, select the Silverlight Class Library project type and enter ContosoAutomotive.Common.SL in the Name field.

    Figure 1

    Add ContosoAutomotive.Common.SL Silverlight class library project (C#)

    Figure 2

    Add ContosoAutomotive.Common.SL Silverlight class library project (Visual Basic)

  4. In the New Silverlight Class Library options dialog accept the default settings. Ensure Silverlight 4 is selected in the Silverlight Version list.

    Figure 3

    New Silverlight Class Library options dialog

  5. Only in Visual Basic, change the root namespace of the ContosoAutomotive.Common.SL project to ContosoAutomotive.Common. To do this, right click the ContosoAutomotive.Common.SL project node and select Properties. In the Properties page, select the Silverlight tab and change the Root namespace field value to ContosoAutomotive.Common.

    Figure 4

    Change Root namespace to ContosoAutomotive.Common (Visual Basic)

  6. Remove the auto-generated class file. To do this, right click on the Class1.cs (C#) or the Class1.vb (Visual Basic) file and select Delete.
  7. You will reuse all the code already present in the existing projects by linking the previous class files in the new projects. To do this, right click the ContosoAutomotive.Common.SL project node and select Add | Existing Item. In the Add Existing Item dialog browse one folder up and select all the class files inside the ContosoAutomotive.Common folder. Then, from the Open button drop-down list, select Add As Link.

    Figure 5

    Add linked files to the ContosoAutomotive.Common.SL project (C#)

    Figure 6

    Add linked files to the ContosoAutomotive.Common.SL project (Visual Basic)

  8. After adding the link to the class files, your solution should like the following image.

    Figure 7

    Linked files in the ContosoAutomotive.Common.SL project (C#)

    Figure 8

    Linked files in the ContosoAutomotive.Common.SL project (Visual Basic)

  9. Repeat the same process for the ContosoAutomotive.Extensions project creating the ContosoAutomotive.Extensions.SL Silverlight Class Library project. To do this, right click the ContosoAutomotive solution node and select Add | New Project. In the Add New Project dialog, select the Silverlight Class Library project type and enter ContosoAutomotive.Extensions.SL in the name field. Remember to select Silverlight 4 in the Silverlight Version list.
  10. Add a reference to the MEF library on the ContosoAutomotive.Extensions.SL project. To do this:
    1. Select the ContosoAutomotive.Extensions.SL project in the Solution Explorer and select Project | Add Reference… The Add References dialog appears.
    2. Select the .NET tab and then select the System.ComponentModel.Composition component. Click the OK button to add a reference to this library.

      Figure 1

      Add a Reference to the MEF library.

  11. Also, add a reference to the ContosoAutomotive.Common.SL library on the same project. To do this:
    1. Select the ContosoAutomotive.Extensions.SL project in the Solution Explorer and select Project | Add Reference… The Add References dialog appears.
    2. Select the Projects tab and then select the ContosoAutomotive.Common.SL component. Click the OK button to add a reference to this library.

      Figure 1

      Add a Reference to the ContosoAutomotive.Common.SL library.

  12. Remove the auto-generated class file Class1.cs (C#) or Class1.vb (Visual Basic) and create a link to all the class files in the ContosoAutomotive.Extensions folder.

    Figure 9

    Linked files in the ContosoAutomotive.Common.SL project (C#)

    Figure 10

    Linked files in the ContosoAutomotive.Common.SL project (Visual Basic)

Task 2 – Create Silverlight Cash Maker UI

In this task, you will create a new Silverlight application to reproduce the same user experience we found in the WPF Cash Maker application.

  1. You will start adding a new Silverlight 4 application project to your solution. To do this, right click on the ContosoAutomotive solution node and selecting Add | New project. In the Add New Project dialog, select Silverlight Application as the project type and enter ContosoAutomotive.Silverlight in the project name field.

    Figure 11

    Adding Silverlight 4 project (C#)

    Figure 12

    Adding Silverlight 4 project (Visual Basic)

  2. In the New Silverlight Application options dialog accept all defaults. Ensure Silverlight 4 is selected in the Silverlight Version list.

    Figure 13

    New Silverlight Application options dialog

  3. Copy all the images files from the ContosoAutomotive WPF project into the Silverlight version. To do this, right click on the Images folder in the ContosoAutomotive project and select Copy. Then, right click the ContosoAutomotive.Silverlight project and select Paste.
  4. Add a reference to the MEF library on the ContosoAutomotive.Silverlight project. You will include the Initialization assembly as well. To do this:
    1. Select the ContosoAutomotive.Silverlight project in the Solution Explorer and select Project | Add Reference… The Add References dialog appears.
    2. Select the .NET tab and then select the System.ComponentModel.Composition and the System.ComponentModel.Composition.Initialization components. Click the OK button to add these references to the project.

      Figure 1

      Add a Reference to the MEF library.

  5. Add a reference to the System.Windows.Controls.Data and System.Windows.Controls.Data.Input on the ContosoAutomotive.Silverlight project. The Cash Maker UI will use these libraries to show data. To do this:
    1. Select the ContosoAutomotive.Silverlight project in the Solution Explorer and select Project | Add Reference… The Add References dialog appears.
    2. Select the .NET tab and then select the System.Windows.Controls.Data and the System.Windows.Controls.Data.Input components. Click the OK button to add a reference to this library.

      Figure 1

      Add a Reference to the System.Windows.Controls.Data and Data.Input libraries.

  6. Also, add a reference to the ContosoAutomotive.Common.SL and ContosoAutomotive.Extensions.SL the library on the ContosoAutomotive.Silverlight project. To do this, right click on the project and select Add Reference. In the Add Reference dialog, select the Projects tab and choose the ContosoAutomotive.Common.SL and ContosoAutomotive.Extensions.SL libraries.
  7. Remove the default MainPage.xaml file in order to replace it with the Cash Maker UI. To do this, right click on the MainPage.xaml file and select Delete.
  8. Include the prebuilt version of the Cash Maker UI located in the Assets folder. To do this, right click the ContosoAutomotive.Silverlight project node and select Add | Existing item. In the Add Existing Item dialog, browse the Assets folder and selecting the folder that matches the language of your choice add the CashMaker.xaml file. The code behind file will be automatically included as well.

    Figure 14

    Add prebuilt Silverlight Cash Maker UI (C#)

    Figure 15

    Add prebuilt Silverlight Cash Maker UI (Visual Basic)

    Note:
    The only differences between the version that you were using on the previous step and the recently added from the Assets folder are that the last one uses the Silverlight control (instead of the WPF version of those), and does not have implemented some code that you will add in the following steps.

Task 3 – Update Your Silverlight Application to Load Composable Parts

In this task, you will modify a Silverlight 4 application to load composable parts using MEF. You will use the same approach used in the WPF version of the Cash Maker application.

  1. Open the App class in Code View. To do this, right-click on the App.xaml file in the Solution explorer and select View Code.
  2. Update the App class to use the MEF library. To do this, add the following statement on top of the using clause list above the App class definition.

    C#

    using System.ComponentModel.Composition.Hosting;

    Visual Basic

    Imports System.ComponentModel.Composition.Hosting

  3. You now will modify the Application class to load the new CashMaker UI. In addition, you will prepare you application to load any available Composable Part from the Silverlight package. To do this, replace the code inside the Application_Startup method with the following code.

    (Code Snippet – Intro to MEF Lab - Ex3 Task2 Step3 - Application_Startup CSharp)

    C#

    private void Application_Startup(object sender, StartupEventArgs e)
    FakePre-0a109e91745f4c0f9378dc84c105ecd9-9ee1e030c8a84fe2b32f46d53efd8845 var catalog = new AggregateCatalog(new DeploymentCatalog()); var container = new CompositionContainer(catalog); this.RootVisual = container.GetExportedValue<CashMaker>();FakePre-675302d696f8476ab202f6fc88eaa348-68f9d2352bed47b68cf580153ad9671cFakePre-f31319ff2dc9457fbf3ae6299fedc29a-e487ae4d91db4131886ec0f5e4c84a39

    (Code Snippet – Intro to MEF Lab - Ex3 Task2 Step3 - Application_Startup VB)

    Visual Basic

    Private Sub Application_Startup(ByVal o As Object, ByVal e As StartupEventArgs) Handles Me.Startup
    Dim catalog = New AggregateCatalog(New DeploymentCatalog()) Dim container = New CompositionContainer(catalog) Me.RootVisual = container.GetExportedValue(Of CashMaker)()FakePre-1a9d7746ffc3450483af2eba3c2c66a1-5eee450b1041435981b912ddc0e675e0FakePre-02f12bc31ca6433a91abb6fe41ba9a60-b00907f868b447daa15af1e0caaeb562

    Note:
    As you did for the WPF version, you create a container which discovers the composable parts through a Catalog. The main window is also retrieved using the GetExportedValue of the container.

    Note:
    Silverlight applications runs and are deployed in a different way that WPF applications, it causes that there is a new catalog on MEF Silverlight version. This exercise uses an Aggregate Catalog (which is also available on the WPF version) including the new Deployment Catalog which download a Silverlight Package (.xap), if it was not downloaded before, and searches for composable parts inside it. As the Deployment Catalog is instantiated without any parameter, it will look for parts inside the Silverlight Package that contains the application.

  4. Since the CashMaker class is now a composable part, you will export the class making it available to the composition container. To do this, decorate the CashMaker class with the Export attribute as shown in the code below.

    C#

    [Export]
    public partial class CashMaker : UserControl, IPartImportsSatisfiedNotification
    FakePre-30461014c93145498d6485681ef6926f-bffdbb3617c240fdb01a54b724e4c5e5FakePre-ecb43c7a7e7a47509d76047d7a6b282d-ec7e1f345a5646128e432c6c83df0dd9FakePre-163076c5f8b44ba589d0bca6425b6296-92826f70d5bf4e66ab92d67a2a173a8c

    Visual Basic

    <Export()>
    Class CashMaker
    FakePre-2b1d7de5e8b54e57bfff2edb1da56064-81ba234a83d84aae991a4f980d2a40d5FakePre-3c4da79636ae4a21a9c4b6f757c3cdfd-0f7e7777b44e4489bb532ef6958881fcFakePre-b2eadbf5b9c9431ea8d31205d6b89700-c2978a8fc4094062a9c3dcd3a776754fFakePre-fc28d9dc49d9490390404ef10958e031-10fc2d0d92824f19b72b208ce2b94057

  5. Add the collection of Lazy object containing the contract implementations that will be populated by MEF. To do this, add the following code to the CashMaker.xaml.cs (C#) or CashMaker.xaml.vb (Visual Basic) file, just above its constructor.

    (Code Snippet – Intro to MEF Lab - Ex3 Task2 Step5 - SilverlightCarQueries CSharp)

    C#

    [ImportMany(AllowRecomposition = true)] public ObservableCollection<Lazy<ICarQuery, IQueryMetadata>> CarQueries { get; set; }

    (Code Snippet – Intro to MEF Lab - Ex3 Task2 Step5 - SilverlightCarQueries VB)

    Visual Basic

    <ImportMany(AllowRecomposition:=True)> Public Property CarQueries As ObservableCollection(Of Lazy(Of ICarQuery, IQueryMetadata))

  6. Modify the implementation of the IPartImportsSatisfiedNotification interface and bind the CarQueries collection to the UI by setting the DataContext property of the commandGrid control. To do this, paste the following code inside the CashMaker’s OnImportsSatisfied method.

    (Code Snippet – Intro to MEF Lab - Ex3 Task2 Step5 - OnImportsSatisfied CSharp)

    C#

    public void OnImportsSatisfied()
    FakePre-4c56d7e1a5404d488242bec3d9609abe-7cf6874e53af4036bff51a9e026c33ab this.commandGrid.DataContext = this.CarQueries;FakePre-4023f7bb93974f8cb0fd56f709d4695e-13cda84bd64f4ade92d13fcde10fc21a

    (Code Snippet – Intro to MEF Lab - Ex3 Task2 Step5 - OnImportsSatisfied VB)

    Visual Basic

    Public Sub OnImportsSatisfied() Implements IPartImportsSatisfiedNotification. OnImportsSatisfied
    Me.commandGrid.DataContext = Me.CarQueriesFakePre-b8137d9e08ac49bf80e734f78b5648da-55b53f27b7ac4d7099b5c66d07ab4fe1

Task 4 – Load Silverlight Extensions Dynamically

In this task, you will create a new Silverlight 4 application and setup your application to load MEF parts dynamically by downloading a new Silverlight package. Additionally, you can mix CLR languages and create the new project in different CLR language than your main application.

  1. Create the ContosoAutomotive.Woodgrove.SL project reusing the classes in the ContosoAutomotive.Woodgrove Class Library project selecting a different language for the project than the main application. To do this, right click the ContosoAutomotive solution node and select Add | New Project. In the Add New Project dialog, select the Silverlight Application project type and enter ContosoAutomotive.Woodgrove.SL in the name field.
  2. In the New Silverlight Application options dialog select the existing ContosoAutomotive.Silverlight.Web project to host the Silverlight application and ensure Silverlight 4 is selected in the Silverlight Version list. Also, remove the Add a test page option in the option section and press OK.

    Figure 16

    New Silverlight Application options dialog

    Note:
    Remember that Silverlight Application projects are packaged into Silverlight Packages (.xap). In the other hand, Silverlight Class Library projects are included inside the application package that references the library. For that reason, you create the ContosoAutomotive.Woodgrove.SL project as a Silverlight application to be able to deploy it in a separated way allowing download it while the Silverlight Main application is running.

  3. After creating the project remove the auto-generated files App.xaml and MainPage.xaml and create a link to the WoodgroveQuery class files in the ContosoAutomotive.Woodgrove folder.
  4. Add a reference to the MEF library on the ContosoAutomotive.Woodgrove.SL project. To do this, right click on the project and select Add Reference. In the Add Reference dialog, select the .Net tab and choose the System.ComponentModel.Composition library.
  5. Add a reference to the ContosoAutomotive.Common.SL library on the ContosoAutomotive.Woodgrove.SL project. To do this, right click on the project and select Add Reference. In the Add Reference dialog, select the Projects tab and choose the ContosoAutomotive.Common.SL library.
  6. Now, your solution is prepared for creating a Silverlight 4 version of the Cash Maker application.

    Figure 17

    All projects converted to Silverlight Class Library projects (C#)

    Figure 18

    All projects converted to Silverlight Class Library projects (Visual Basic)

  7. Modify the ContosoAutomotive.Silverlight application class code to create a catalog to download the new Silverlight package. To do this, replace the catalog definition code inside the Application_Startup method with the following.

    (Code Snippet – Intro to MEF Lab - Ex3 Task4 Step7 - UriDeploymentCatalog CSharp)

    C#

    private void Application_Startup(object sender, StartupEventArgs e)
    FakePre-da5e8a3c4a3e43c1b1568acdb9459356-c4f3481bcebe4f0fb5cdfe6122fe79a8 var xapCatalog = new DeploymentCatalog("/ClientBin/ContosoAutomotive.Woodgrove.SL.xap"); xapCatalog.DownloadAsync(); var catalog = new AggregateCatalog(new DeploymentCatalog(), xapCatalog);FakePre-9e175b4546344f619f1826beb1e139de-3f6d6c0de3ab4afb86a1dca24bfc7de0FakePre-56730ed276c44ee1a667a4001dc5211f-915b2eaa62e84a778a99d9d1e33f1456FakePre-38b9f93c33de44ed9bf52565dd99a576-f20b93c685ba43e5a3267b089e3467b5FakePre-feaa9d4592154d51b556d59f83c4e61a-4943d92de5e14c58a75283bf405e5b4cFakePre-acec56bde10d459c905e594122766abb-bf0dc38718bf41978cf61dab5063a009

    (Code Snippet – Intro to MEF Lab - Ex3 Task4 Step7 - UriDeploymentCatalog VB)

    Visual Basic

    Private Sub Application_Startup(ByVal o As Object, ByVal e As StartupEventArgs) Handles Me.Startup
    Dim xapCatalog = New DeploymentCatalog("/ClientBin/ContosoAutomotive.Woodgrove.SL.xap") xapCatalog.DownloadAsync() Dim catalog = New AggregateCatalog(New DeploymentCatalog(), xapCatalog)FakePre-864beabadbf7441f9a31989aed2865d0-95da90edb105483ea7ab9c91c765fde0FakePre-8efc962770a0496ab77866436c87d3e9-e1e1452e427f41e4a403ea64b28fafc1FakePre-00a3a342b5ff4600a364d93b0869f5e9-9199f992d1014b21af042a8f3cc7f21eFakePre-53e274df56144b35b6de730f26b4915f-64c453aeb8424ee1b859c97b37ed146e

    Note:
    In the code above, a new Deployment Catalog is included to the Aggregate Catalog. Because it is instantiated specifying a url where a Silverlight Package (.xap) is available, it will be in charge of download it and find the composable parts inside it.

    The call to the DownloadAsync method of the DeploymentCatalog object forces to download the package (it is performed in a separated thread). Take into account that the package will not be downloaded until this method is called.

Next Step

Exercise 3: Verification