Prism 4 Region Navigation with Silverlight Frame Navigation and Unity


I have had several requests to demonstrate how to use Unity with Prism 4 Region Navigation and the Silverlight Frame Navigation framework.

The primary purpose of this blog post is to provide an example of using Unity for dependency resolution when writing a Silverlight application that also uses Prism 4 Region Navigation and the Silverlight Frame Navigation framework.

Required Reading

If you have not yet read these blog post please do so now.

These blog posts provide critical foundational information that will not be repeat in this blog post.

Example Code

This blog post is a direct port of the code from the above Cancelling a Navigation Request using Prism v4 Region Navigation with Silverlight Frame Navigation post that uses MEF for dependency resolution.  That code has been ported to use Unity instead. 

The code in this blog post includes the prompt for navigation cancelling feature that gets called when navigating away from the inventory item page. This prompt demonstrates implementing the IConfirmNavigationRequest.ConfirmNavigationRequest method in Silverlight when the Silverlight Frame Navigation framework is also being used.

Configuring the Unity Container

When using Unity with Prism 4 Region Navigation in either Silverlight or WPF applications, the Unity container needs to be configured in a special way.  This is required because of the way the Prism Region Navigation API requests objects from the Unity container.

The below text is taken from the “Basic Region Navigation” section of on Prism 4 MSDN documentation page: http://msdn.microsoft.com/en-us/library/gg430861(v=PandP.40).aspx

ConfiguringUnity

The following code snippet is from the Bootstrapper.cs file in the, “ThePhoneCompany” project.  This shows how to properly register views with Unity that will be navigated to using the Prism 4 Navigation API.  The views are registered as type Object and then the type full name is used to name the view in the Unity container.

Notice how I have chosen to use the type full name instead of the type name.  Using the type full name prevents name collisions across different modules and makes navigating across modules very easy.

protected override void ConfigureContainer() {
    base.ConfigureContainer();

    Container
        .RegisterType<Object, AboutView>(typeof(AboutView).FullName)
        .RegisterType<Object, HomeView>(typeof(HomeView).FullName);
}

The below UriMapper XAML is from the ShellView.  You can see how the above view type full names map to the below Urls. 

Example:  User navigates to /#/HomeView, the Region Navigation API will request the “ThePhoneCompany.Views.HomeView” named object from the Unity Container and begin the navigation process. 

Example: User navigates to /#/Inventory/ItemView/1009, the Region Navigation API will request the “ThePhoneCompany.Inventory.Views.ItemView” named object from the Unity Container and begin the navigation process.

<navigation:Frame.UriMapper>
    <uriMapper:UriMapper>
                        
        <!--Default applicaiton mapper-->
        <uriMapper:UriMapping Uri="" MappedUri="/ThePhoneCompany.Views.HomeView"/>
                       
        <!--Used to add a new record-->
        <uriMapper:UriMapping Uri="/{moduleName}/{pageName}/add" MappedUri="ThePhoneCompany.{moduleName}.Views.{pageName}?key=0"/>
                        
        <!--Used to edit a record-->
        <uriMapper:UriMapping Uri="/{moduleName}/{pageName}/{key}" MappedUri="ThePhoneCompany.{moduleName}.Views.{pageName}?key={key}"/>

        <!--Used to view a page-->
        <uriMapper:UriMapping Uri="/{moduleName}/{pageName}" MappedUri="ThePhoneCompany.{moduleName}.Views.{pageName}"/>
                        
        <!--Used to navigate to a page in the Shell-->
        <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/ThePhoneCompany.Views.{pageName}"/>

    </uriMapper:UriMapper>
</navigation:Frame.UriMapper>

The below code snippet is from the InventoryModule.cs file.  Notice again how the views are registered in the Unity Container as type Object and named using the type full name.

public class InventoryModule : IModule {

    public InventoryModule(IUnityContainer container) {
        container
            .RegisterType<InventoryViewModel>()
            .RegisterType<ItemViewModel>()
            .RegisterType<CategoryViewModel>()
            .RegisterType<Object, InventoryView>(typeof (InventoryView).FullName)
            .RegisterType<Object, ItemView>(typeof (ItemView).FullName)
            .RegisterType<Object, CategoryView>(typeof (CategoryView).FullName);
    }

    public void Initialize() {
           
    }
}

Running the Sample Code

Requirements: you must download Prism 4 or later and run the RegisterPrismBinaries.bat batch file. The Prism v4 Readme covers this file in detail. If you do not want to run this batch file, you’ll need to remove and re-add the references to the Prism assemblies.

The attached code uses Unity for dependency resolution.  This code also demonstrates cancelling a navigation request. To see this in action, run the application, select Inventory in the menu bar, select an inventory item to edit, then press the Close button on the inventory item form. A MessageBox will prompt you to continue the navigation or cancel it.

Comments

Microsoft values your opinion about our products, guidance, documentation and samples.

Thank you for your feedback and have a great day,

Karl Shifflett

SLPrismNavigationUnity.zip

Comments (15)

  1. Carl says:

    Brilliant. Thank you Karl.

  2. Faress says:

    thank you for taking the time to do this

  3. kumarsomu says:

    Hi Karl,

    Your example looks pretty good. I am in urgent need to take some decision to use this in my application which  should be multitargetting. Can you please reply me is it reusable with WPF(especially viewmodel classes)? I appreciate your reply asap.

    Thanks

    kumarsomu

  4. Kumarsomu,

    Yes, Prism region navigation works the same for both Silverlight and WPF.

    Karl

  5. Kumarsomu says:

    Thanks Karl. Is there any specific Visual Studio Project Template for region navigation application? Because in your example, modules. shell project and file structure looks different?

    Thanks

    Soma

  6. Soma,

    No, there is no specific template for using region navigation.  

    However, Visual Studio has a template for Silverlight Navigation Applications.

    Karl

  7. CyclingFoodmanPA says:

    Hey Karl,

    I have been following your In-The-Box MVVM training and am working on a large application utilizing SL, Csla (Rocky Lhotka), Prism (Unity), Telerik Controls.  I have my application loading modules dynamically based in module definitions in a ModulesCatalog.xaml file.  Does this methodology (the navigation) work with modules dynamically loaded also.  I noticed your MyPhoneCompany.Inventory is a SL Class lib and not an Application.  I love the way you can be working on something (Inventory Category) and if interrupted, can go to something else, and then come back to what you are working on as this is a real world scenerio in most businesses.  I do wonder if there is a limit as to how many items you can have open and working on at the same time.

    Anyway, great job Karl.  Just as I get .NET 4 and Prism 4 figured out, I bet you guys will come out with .NET 5 and Prism 5!

    CyclingFoodmanPA

  8. CyclingFoodmanPA,

    I have not run into any limitations with this approach.  I also did this in my BBQ Shack and my new soon to be released BBQ Shack v2 (WPF & Prism)

    Cheers,

    Karl

  9. Kumarsomu says:

    Hi Karl,

    I tried to reuse the silverlight unity sample in WPF. I tried replacing navigation frame with Itemcontrol.It creates duplicate views. then replaced with contentcontrol. It doesn't replace views. then replaced with Tab Control. creates duplicate views.

    Apart from this, when i click navigate button, i could not navigate(or replace view) using RegionManager.Requestnavigate method. views are displayed only using registerviewwithregionname method only. but the same code working in silverlight. Also activate view method also not showing view.  i could not figure out what would be the issue. I reused all the projects in wpf. except framenavigation dll . could you figure out to what i am mistaking?  

  10. Kumarsomu,

    Check out this WPF application here:

    blogs.msdn.com/…/patterns-and-practices-2010-symposium-content.aspx

    It uses MEF, easy to convert to Unity.  This will help you get started.

    Cheers,

    Karl

  11. Krish says:

    Hi Karl,

    Thank you for the code. It was very helpful in understanding how to integrate Prism 4 with the Silverlight Navigation application. I really liked the concept the keeping the views (inventory & category) open and going back to it.

    Can we achieve similar result (keeping the views open) in an application integrating Prism 4 / Unity with Standard Silverlight Application (Not business / navigation application)? Is there an example or documentation i can refer to?

    Thank you,

    Krish.

  12. Krish,

    Very easily.  This is the core scenario for Regions in Prism.  The Prism Navigation API make this very simple to implement.

    Please read this:  blogs.msdn.com/…/prism-v4-region-navigation-pipeline.aspx

    Also the Navigation chapter on MSDN: msdn.microsoft.com/…/gg430861(v=PandP.40).aspx

    Cheers,

    Karl

  13. krish says:

    Thank you for the quick reply.

  14. CyclingFoodmanPA says:

    Hi Karl,

    Is there a good example/explanation on how to implement authentication (users and roles) within a SL4, Prism, application.  I have a DB with custom tables User, Role, UserToRole and I want to be able, based on login and roles, to load particular modules to perform CRUD operations on.  I have searched and searched and found bits and pieces on how to do this, but no full blown explanations and examples.  Any help in steering me in the right direction would be great.

    Thanks for everything Karl,

    CyclingFoodmanPA

  15. CyclingFoodmanPA,

    I don't have a full blown example.

    I would have the user log in, then load modules based on their log in permissions.  You can have a service return the application the module catalog as part of the login and then load those modules.

    You can also tie this to Forms Authentication so that the user logs in using an ASP.NET Forms Authentication form, as a result of that form, redirect to the web page with the Silverlight application.  This page will have the authenticated user and can get the module catalog from the web server.

    Does this help?

    Karl