At times there may be a need for a Silverlight app to be re-used as a whole in another Silverlight app. For e.g. I have a generic web tool that needed to be integrated into several other Silverlight applications without rewriting the GUI layer again. I couldn’t have exposed the functionality as a web-service because the tool required user interaction in terms of data input and since this data input had to be similar for every application that its going to be used from, I decided that embedding was the best way forward rather than duplicating the GUI logic for every host app.
In this post, I show how to embed one app into another using the .xap file and loading assemblies on the fly. The GUI thus created would then interact with WCF RIA service to access database, get data, take some user input, do some processing and spit out a CSV file as output.
Assuming you already have the Silverlight app that you need to embed ready (hereby called as Main app), I now show how to embed it.The hosting app is a Silverlight Web App with WCF RIA Services enabled, called StoreRankerHost. The solution structure looks like this:
This app has a main page with a simple HyperLink button that when clicked would open a child window (StoreRankerChild.xaml) and in this child window I am going to load my Main App. The code for the child window looks like this:
In the constructor, I am using a WebClient to read/load the .xap file and adding an event handler for the OpenReadCompleted event. The xap file is basically a zipped package for all the dlls that a silverlight app needs during its runtime. When the app first runs, this xap is downloaded to the client machine and used from there. By building a relative Uri for the xap file we can rest assured that Silverlight would find the file from the appropriate location on the client computer.
In the event handler, I am loading the main StoreRanker.dll (i.e. resource) from within that xap and loading the assembly dynamically by a call fo the Load() method of AssemblyPart class. Finally, I am building the main GUI by creating an instance of the StoreRanker.MainPage class and rendering it within the LayoutRoot of the hosting window as shown below:
And that’s it! for communication with WCF RIA services, I added my pre-existing service into the ASP.NET website’s RIAServices folder as shown in the solution structure at the beginning. Also make sure that the xap file for the main app is in the ClientBin folder of the hosting app as well. The reason for this is that xap file can only be used to render the client, all the server side interactions would still have to be added separately to the website which includes any web.config settings like connection strings, global settings in Global.asax file and any file i/o etc. When the user interactions on the hosted app happen, the app would automatically resolve the call to the web service correctly if the service class has been added to the hosting website.
I did quite a bit of Googling on this subject and stumbled upon this link that proved quite helpful: Load Assemblies On Demand . I hope my post would help people who are looking to solve a similar problem.