Monday, July 19, 2010

Loading Assembly dynamically (on demand) in Silverlight 4


It’s an important architectural pattern to keep the size of your initial ZAP file minimal to provide a fast initial loading experience to the user.
To make this happen Silverlight provides facilities so that you can load assemblies as and when required.

This should be the Architectural Design of your app:

  1. Make your application modular and divide it in smaller assemblies.
  2. Load required assemblies when required

Tip: You can also load built in assemblies at run time on demand. For example toy can load Dot Net assembly

I have written a walkthrough tutorial.
You need Visual Studio 2010 express (or higher) and Silverlight 4.0 installed.

The example app loads an assembly called SilverlightLibrary.dll when the user clicks a text block. This example uses a relative URI to load the assembly from the same location as the application XAP file. It can be loaded from other locations as well.

This example uses the WebClient class to initiate an asynchronous download of the assembly in response to a user mouse click. When the download is complete, the AssemblyPart class is used to load the assembly.

1. Setup the project

Create a New Silverlight application and Name it : LoadingAssemblyOnDemand


2. Click ok when the following prompt pops up:


3. Now you have two projects in your solution, one is Silverlight App and another is a webApp
    to host this Silverlight App as seen in the Solution explorer below


4. Add the following elements into your MainPage.xaml.
This will build up our basic GUI. Clicking on the Text block will initiate the process of dynamic loading on demand.

<TextBlock>Page from Host 
Click Here to Display a UI from the Library 

As seen in the screen shot below:


5. This will create a simple UI which you can see in the design view.


6. Now open the code window (MainPage.xaml.cs) and add the following code to the class.

private void TextBlock_MouseLeftButtonUp(
            object sender, MouseButtonEventArgs e)
            // Download an "on-demand" assembly.
            WebClient wc = new WebClient();
            wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
            wc.OpenReadAsync( new Uri("SilverlightLibrary.dll", UriKind.Relative));
        private void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
            if ((e.Error == null) && (e.Cancelled == false))
                // Convert the downloaded stream into an assembly that is
                // loaded into current AppDomain.
                AssemblyPart assemblyPart = new AssemblyPart();
        private void DisplayPageFromLibraryAssembly()
            // Create an instance of the Page class in the library assembly
            SilverlightLibrary.SilverlightPage page = new SilverlightLibrary.SilverlightPage();

7. Add a new project of type Silverlight Class Library to the Solution. Name this Project as SilverlightLibrary
    Now the solution has three projects as shown below:


8. Add a class to this newly added class library project. name this Class as SilverlightPage.cs, as shown above.

9. Add a simple method to this class named – ShowMessage and the code as shown below-

public void ShowMessage(string messsage)

So when the user will click on the text block in the Silverlight app, this assembly and this class (SilverlightPage) will be dynamically loaded and this method can be called on the class object.

10. Now build this Class Lib project as shown below:
      (Right Click on the Project Node and Click on Build)


11. Now you have to add reference of this class lib into your Silverlight app.
(For this expand the Silverlight App Project Node, right Click on References Node and Click Add Reference…)


12. Add reference dialog box opens. Click on the Project Tab and
      select the SilverlightLibrary (Class lib), click Ok) as shown below-


13. You will see a Reference of the Class lib added to the References Node Of the project as shown below-


14. Right Click on the SilverlightLibrary Node of the references as shown below and Click on Properties


15. Properties dialog box opens. Set the Copy Local property to False, as shown below and then save the project and solution.


16. Now build the Silverlight App.

17. We also need to copy the compiled DLL file of the class lib to the Client Bin Folder
      of the web project (On-Demand-Assembly-Loading.Web).
      So navigate the Solution Folder and then web Project folder and the Bin folder>
      For me the path was like this:
      C:\Users\SUMIT\Documents\Visual Studio 2010\Projects\On-Demand-Assembly-Loading\SilverlightLibrary\Bin\Debug

      Copy two files from here (SilverlightLibrary.dll and SilverlightLibrary.pdb) and paste it to the Client Bin Folder of the Web Project.
      My Web project looks something like this after doing this-


18. Now we are done, So run the Silverlight Application. this will open the Default test page in the browser.
      We need to test whether the SilverlightLibrary assembly is being loaded dynamically at runtime.
      Firebug in Firefox can help us in this.
      Open FF and Open the Firebug pane. Enable Net tab in firebug to see the network traffic.
      Load the test page in Firefox and examine the traffic.
See after the first loading of the page, the XAP file loads that takes 4.3 KB of traffic.
The SilverlightLibrary assembly has not been loaded till now.
There are total 5 http requests making a total of 15.3KB. See below-


19. Now Click on the TextBlock to fire up the dynamic loading process.

     A welcome message box pops up this means the dynamic code is executed.
     See, there are now six http request and Total is now 19.3KB.

20. When you expand the last (sixth request) you will see the name of the SilverlightLibrary.dll assembly.
This was loaded dynamically when user clicked on the text block.


So this walkthrough helps us to understand the complete process of making our Silverlight Application
modular and help us load the assemblies dynamically at runtime from the server.

Pls. put your comments or any questions. i shall love to answer you.

Few useful references:

MSDN Tutorial: How to: Load Assemblies On Demand
MSDN Sample: How to: Load Assemblies On Demand Video: Loading Dynamic XAPs and Assemblies

Install Silverlight On-demand loading of assemblies with Silverlight Navigation - SilverLight : Load Assembly on Demand