Silverlight 3 Navigation: Even more on Dynamically Loaded Pages

I got a lot of great feedback on my post Silverlight 3 Navigation: Dynamically Loaded Pages… Now MEF Powered!

Dinesh Chandnani decided to do an update to this sample after looking at the feedback and talking to Nikhil Kothari and Wes Haggard from the MEF dev team.   The goals for this update are:

  1. Show even more of a web like user model.  With the web, you often see all the links in the navigation, but the actual page only downloads once the user clicked the link. 
  2. Lose coupling.  I need to be able to be able dynamically add, update even remove pages from my application without taking down the app and without rebuilding it.
  3. Built in authentication.  In real business apps, we need to protect our data, so authentication is  very important.  The web has popularized a very interesting model where you are only asked to authentication when you try to do an operation that needs it.  For example, i can browse the netflx catalog any time, but I have to log in the minute I try to add something to my queue. 

Download the all the source code


Basic Authentication and User Settings

Let’s do a quick run through of what the app does (with no extensions just yet). 


As you can see, it is the basic Silverlight Business Application template with Home and About pages that you can navigate to.  As well as a log in button.  But also notice there is a User Settings page who’s link is red which indicates the user needs to log in to see the contents of the page.  So if I log in as a user (Login: guest        Password: guest**)


I am now logged in and can access the Site Settings page, so it is no longer red.


On this page, I can edit user level customization of the app.  In this case, the background color of this page.  This data is stored on the server is the ASP.NET profile store, so each user can have their own settings that will work on any machine they go to. 


To bring that point home, let’s go in and create a new user, and give that user a different background color. 

Click on login


then Register Now


I registered “guest3”..

Now, i set the background color to be yellow


Then I log out and log in as guest and it is back to red.


Oh, and what is even more cool, is if you haven’t noticed yet, if you are not logged in, and you click on a link that requires authentication, you are prompted to log in and then the page is shown to you!  Very web like.



Loading Extensions

Ok – that is cool and all, but this is a MEF blog post, so we have to talk about application extensibility right?  The scenario here is that you are building a composite applications that may have many possible pages.  The pages that are there are available maybe very dynamic… it may depend on who the logged in user is, in a multi-tenant environment  it may depend on the service level of the client, it may also depend on what has been developed yet.  In all those cases, we don’t want to rebuild the app each time there is a new extension, in fact we don’t even want to take the app out of production.  We’d like to simply xcopy the AdditionalPages.xap extension into a directory and instantly the right clients have access. 



Simply hitting refresh on the application makes two new pages show up “products” and “site settings”


Clicking on the “products” link causes the AdditionalPages.xap to be downloaded. 


Once the xap is downloaded the page displays



Once the xap is downloaded users can navigate between the pages with no delay.


As an aside, this xap also includes a page that only an admin can access.  So if you log in as a user, you still can’t access it. 

Not logged in at all, you can’t access user or site wide settings


Logged in as a guest, you can access only user settings


Logged in as admin, you can access both site and user settings



Communicating Between Exceptions

What we have shown so far is loading of isolated pages dynamically.. while that is very cool, what is more interesting is where these pages have to interact together.  For example, sharing data between pages.  As you might guess, MEF has a model that fits in very nicely here. 

If you check out the products page, it actually has access to information about the currently logged on user. 


It gets this information from the main silverlight application via an import.  In products.xaml.cs, we are importing the RiaContext (which includes information about who is logged in). 

   1: [Import]
   2: public RiaContextBase RiaContext
   3: {
   4:     get { ... }
   5:     set { ... }
   6: }

and in the Silverlight application, in Services.cs we are exporting the RiaContext which is populated from the server. 

   1: public static class Services
   2: {
   3:     [Export]
   4:     public static RiaContextBase RiaContext
   5:     {
   6:         get { ... }
   7:     }
   8: }

When the xap gets downloaded to the client, these exports and imports are resolved. Using this model any pages can share state. 


Adding Additional Pages

What is very cool about this model is how easy it is to add additional pages.

1. Add a new SilverlightApplication



Remove the test page…  



Remove MainPage.xaml and App.xaml..

Add References


DynamicNavigation  – David Poll’s Navigation Extension

System.ComponentModel.Composition – MEF



and add a project reference to PageMetadata



   1: namespace YetMoreAdditionalPages
   2: {
   3:     [PageContent(Name="employees")]
   4:     public partial class EmployeesPage : DynamicPage


Now build, and then copy the YetMorePages.xap over to the extensions directory.  



Hitting F5, now we have our page dynamically loaded!



If you are doing active development, i’d suggest setting the build output directory of the extensions to the extensions directory.   This avoids the explicit copy step each time.





In this example we looked at how to build an authentication aware, composite  silverlight application…  you can download the all the source code ..

Comments (15)

  1. DOB says:

    Is the download correct, I can’t find a login?

  2. BradA says:

    Hmm.. it seems to work for me, there should not be a log in required.  

  3. Robert Kozak says:

    Same thing here. I downloaded twice.. Using link at top and bottom of article. Dynamicloading stuff is there but I don’t see the same thing you are showing in the article. No LogIn link or Site Settings link.

  4. BradA says:

    Ahh — bad day for me… sorry… I had the wrong link up there… should work now.  

    thanks for letting me know..

  5. Dinesh says:

    1 quick thing – the credentials for the admin for this sample is:

    Login: admin

    Password: admin**

    Brad already mentioned above that the credentials for guest is:

    Login: guest

    Password: guest**


  6. Theo Albers says:

    The sample is almost complete 😉 I think there is one missing aspect and that’s support for having multiple instances of the same page type. I’m struggling with this in combination with MEF (see this thread So how would you tweak the navigation manager to allow new instances of a page? Line 161 navigates to the selected page.

    I see that some pages use PartInitializer.SatisfyImports on themself. But this means that the imported parts are shared instances from the root composition container. Basically you would expect the NavigationManager to declare a child container or something and let the target link be created in that scoped context. Or?

  7. JDM says:

    I attached the database but what is the connection string for this.

  8. Bydia says:

    I would like to see a sample of logging into an .aspx page and have that shared with Silverlight… or Logging into Silverlight and have it share with .aspx.  Since Silverlight runs in a page in a website. This situation of having a mix of .aspx/AJAX and Silverlight work together is important.

    Do we have to login, for each environement even on the same site?

  9. Bydia says:

    Would also like to see a sample of a navigation menu that is stored in a database.  Menu item access is associated with roles and thus access can be changed without changing code.  The SQL select would only return menu items that the user has access to.

  10. Very nice app. Does the time thats required to download the XAP files depends on file size ? If so how can we make that as faster download ?



  11. Roger says:

    When I try to use this:

    HttpContextWrapper httpContext =  this.ServiceContext.GetService(typeof(HttpContextBase)) as HttpContextWrapper;

    Inside a LinqToEntitiesDomainService, I get the error:

    This DomainService has not been initialized.

    I can’t see how you setup the DomainService differently than what RIA generates for this to work. Thanks…

  12. Greg Gum says:

    As far as I can tell, there is an additional step to the above to get a dynamic page to display.  When I first tried the above, I got the error:

    No XAML was found at the location ‘/AdditionalPages;component/DynamicPage1.dyn.xaml’.

    The fix on this was to create the shim which is used on the other pages in the example such as ProductsPage.dyn.xaml.

    Also, the easiest way to create a new dynamic page is using the DynamicPage item template from David Polls blog:

    This template subclasses the page for you, as well as creating the shim.

    All you have to do after creating a new page from the template is add

    [PageMetadata.PageContent(Name="Dynamic Page")]

    to the class declaration and it’s good to go.

    Greg Gum

  13. Denis Vuyka says:

    Great article indeed but why source code is no longer available?! All links are broken 🙁

  14. BradA says:

    sorry, my site was down, seems to work now

  15. Ahtisam says:

    Hi there ..

    Great article indeed but I am having some problems

    I already have aspnetdb in my SQL Server but where is the connection string for this so i can connect it qith my localhost.

    And wht is this RAI can you please tell me.