Silverlight with MEF, for dynamic downloading of XAP Files



I rate "multi threading" and "mef" features in Silverlight as the biggest enhancement towards performance enhancement.

MEF i.e. Managed Extensibility Framework is a component of .Net Framework 4.0 and also added support to Silverlight 4.0. It actually simplifies the creation of extensible applications using extensions to develop encapsulated code without any hard dependencies, i.e we can load an assembly on demand from a specific location.

MEF is able to Compose a Silver light Application, out of numbers of very loosely couple (independent) pieces/components/classes (also xap files). By discovering, downloading form a Silverlight Application Server, and composing together the various xap files at the Client side at runtime, thus providing runtime extensibility support for your Silverlight Application
I mean to say we can download asynchronously the desired .XAP files to the client's browser, as required and when we require them into an application at runtime. This would result in a perfect memory management solution by avoiding the unwanted xap files on the client side. Yes a modules based programming.

1.gif

To achieve the above mentioned goal, we use the following features of MEF:

  1. Dependency Injection like functionality enable us to create independent modules.
  2. Runtime composition and Re-composition of components (*.xap files) at runtime.
  3. The Silverlight toolkit has PackageCatalog(mef), it helps in working with another class packages to download separate XAP files, at runtime.

Lets first understand what is "Dependency Injection". Let me draw an analogy here. We all have heard of "Rabies Injection" or "Typhoid injection", wherein the words, rabies and typhoid are diseases, similarly "dependency" has got to be a disease and to cure it we use MEF(dependency Injection).

Let's get started and soon we will encounter dependency problem (a disease), and will cure the same using MEF (dependency injection), extending the solution further, by asynchronous downloading the desired xap file on client side, at runtime. Thus resulting in a perfect memory management solution.

Step 1: create a Silverlight 4 web site project call it "slCarsExample".

2.gif

3.gif

Step 2: add a label + button + ListBox onto the design widow.

4.gif

Step 3: Add a SilverlightClassLibrary project, to the solution and name it "SilverlightClassLibraryCar" and then add a class "SlCarClass", to the project.

5.gif

6.gif

Step 4: Add a Reference to "SilverlightClassLibraryCar" to the "slCarsExample" project and get the label printed with merc value.

7.gif

Step 5: Open SilverlightClassLibraryCar project and change the class name to "ChinaToy" and property to "Cheaptoy" .

8.gif

Will result in the breaking of code...

9.gif

Hence changing the class and property name, results in breaking of code inside araja() method, of our "slCarsExample" project, as it was dependent on the original class and property name... hence a need for mef, to bring out the agile / non breaking solution.

Step 6: Time to introduce MEF framework into the SilverlightClassLibraryCar project by adding the following reference "using System.ComponentModel.Composition;" from this location
"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client"

Step 7: And incorporate the Export attribute with a key "TOY" on the property "CheapToy"

        [Export("Toy")]
        public string CheapToy

10.gif

Step 8: Time to introduce MEF into the slCarsExample project by adding the following reference "using System.ComponentModel.Composition;" from this location
"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client" and also add this reference "System.ComponentModel.Composition.Packaging.Toolkit.dll", from "C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Toolkit\Nov09\Bin".

using System.ComponentModel.Composition.Packaging;
using System.ComponentModel.Composition.Hosting;
using
System.ComponentModel.Composition;
11.gif

Thus the dependency injection is achieved, by introducing MEF (import-export attributes) and by replacing the class instancing part with Package catalog. As a result at run time a perfect discovery and composition will occur based on import and export attribute and the instancing will happen on the fly, at runtime, without implicitly declaring the same.

Catalog is responsible to discover extensions in your application and the Composition Container is responsible to Coordinates, creation and dependency satisfaction.

Now we are free to change the class or property name, the solution will not break at all, hence an agile behaviour is achieved and the dependency problem is cured.

The same feature of runtime discovery and composition can be taken further for downloading asynchronously a particular xap files as and when required. Lets move forward with the solution...and add one more xap file into our existing solution.

Step 9: add a new silverlight project to the solution and name it "AllToys", uncheck the test page.

12.gif

13.gif

Step 10: From "Alltoys" project delete the app.xaml and main.xaml files, this will result in another xap file in our project. Also introduce MEF into the Alltoys project by adding the following reference "using System.ComponentModel.Composition;" from this location

"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client"

Step 11: Add a class to the "AllToys" Project

14.gif

Step 12: Add Reference "AllToys" to "slCarsExample", project

Step 13: Incorporate the following changes in the slCarsExample project.

15.gif

We are using the Import[many] attribute for collection with a feature AllowRecomposition = true. Now on First request, both the xap files would be downloaded on client side, which is not the desired goal.

16.gif

In order to slip the xap files into independent components and to enable download the second xap file at runtime, on the click of button, we need to incorporate the following changes.
  1. In slCarExample project, Right click "AllToys", in the References and select property option. Make the "Copy Local" property to false.

    17.gif
     
  2. The following changes to be incorporated in the button click...

    private void button1_Click(object sender, RoutedEventArgs e)
            {
                Package.DownloadPackageAsync(new Uri("AllToys.xap", UriKind.Relative),   (s, p) => cat.AddPackage(p));
              
                LayoutRoot.DataContext = MyAlltoys;           
              
            }

    18.gif

Now only, on a click of the button the AllToy.xap file will get downloaded on the client side. The discovery, composition and instantiation happens at runtime ... thus loading an assembly on demand from a specific location

In my next article I wish to use mef feature to improve my existing Silverlight mvvm solution.