• Why Silverlight 3 Navigation cannot be fully leveraged when loading modules remotely with Prism 2

    Published by on November 5th, 2009 6:36 am under Composite Application Guidance for WPF & SL, Navigation, p&p, Patterns & Practices, Prism-v2, Remote Module Loading, Silverlight, Silverlight 3, Windows Presentation Foundation, WPF

    6 Comments

    Now that the Prism team has shipped a new version of the guidance, I thought it would be a good time to blog on this subject, based on some research we did with Ezequiel, Matias and Julian. This article will not focus on how to workaround the limitations of using Silverlight 3 Navigation with Prism (as the guys who wrote the posts mentioned below have done a good job on that) instead it will focus on the why of these limitations:

    Warning: Technical explanation coming below.

    The Silverlight team is aware of the limitations mentioned below, so they might be taken into account for a future version.

    Issue Description

    Pages with code behind, from remotely loaded modules cannot be navigated to, calling the Frame’s Navigate method. This prevents having functional views since they neither have code behind nor a ViewModel attached.

    Cause of Issue

    Note: To be able to perform the research below, add the following line in the LoadAssemblyFromStream method placed in the XapModuleTypeLoader class from the CAL:
    Deployment.Current.Parts.Add(assemblyPart);

    The Silverlight 3 Navigation framework goes over every AssemblyPart in the Deployment.Current.Parts collection if the Page to navigate to has code behind, as shown in the code below (PageResourceContentLoader class reflected code in the System.Windows.Navigation namespace from the System.Windows.Controls.Navigation assembly):

    private static Type GetTypeFromAnyLoadedAssembly(string typeName)
            {
                Type type = null;
                foreach (AssemblyPart part in Deployment.Current.Parts)
                {
                    /*THE LINE BELOW RETURNS NULL FOR REMOTELY LOADED ASSEMBLIES, BECAUSE THEY ARE NOT IN THE APPLICATION'S XAP*/
                    StreamResourceInfo resourceStream = Application.GetResourceStream(new Uri(part.Source, UriKind.Relative));
                    if (resourceStream != null)
                    {
                        Assembly assembly = new AssemblyPart().Load(resourceStream.Stream);
                        if (assembly != null)
                        {
                            type = Type.GetType(typeName + "," + assembly, false);
                        }
                    }
                    if (type != null)
                    {
                        return type;
                    }
                }
                return type;
            }

    As the above code shows, even if the AssemblyPart is in the collection it is not found by the Application.GetReourceStream method. From the method’s MSDN site, the cause is:

    “The GetResourceStream method allows you to load an arbitrary resource file from one of the following locations:

    • Embedded in the application assembly in the application package.
    • Embedded in a library assembly that is included in the application package.
    • Included in the application package.”

    So only assemblies in the application’s original .xap file are found and not for other modules.

    I hope the above explanation was useful.

    Shout it

    kick it on DotNetKicks.com

    Tags: , , , , , , , , ,

    • http://bhaidar.net Bilal Haidar

      Hi Damian,
      I have a comment on this:

      “The GetResourceStream method allows you to load an arbitrary resource file from one of the following locations:

      * Embedded in the application assembly in the application package.
      * Embedded in a library assembly that is included in the application package.
      * Included in the application package.”

      So only assemblies in the application’s original .xap file are found and not for other modules.

      Then, why does it load Views with no code-behind? How could she find them then?

      Thanks

    • http://blogs.southworks.net/dschenkelman Damian Schenkelman

      Hi Bilal,
      “The Silverlight 3 Navigation framework goes over every AssemblyPart in the Deployment.Current.Parts collection IF the Page to navigate to has code behind”. If the Page does not have code behind, a different “mechanism” is used. You can reflect Silverlight’s Navigation code to check how it is done.

      Thanks,
      Damian

    • http://weblogs.asp.net/AlexeyZakharov/ Alexey

      Hi,

      I think frame based page navigation is bad. So in my personal opinion Prism page (if it will be in future version) navigation should not relay on it.

      Thanks,
      Alexey.

Archives

Categories