Why can't my solution load modules?

Jul 24, 2012 at 7:08 PM
Edited Jul 24, 2012 at 7:16 PM

I'm having problems with a simple project here, please, I need help.

I'm using SL5, Prism 4.1, Unity.

I'm making a simple solution for studying purposes, but I can't advance since my solution can't load the modules I coded so far, it throws an exception that says that it can't find the module Countries, but it fact, if I don't load the module Countries, the same exception is thrown for the remaining module. I haven't been able to see what the problem is.

Here is the solution structure: 

Here's the Bootstarpper:

public class MyBootstrapper : UnityBootstrapper {
    private const string ModuleCatalogUri =
                            "/MyPrismSolution;component/ModulesCatalog.xaml";

    protected override IModuleCatalog CreateModuleCatalog() {
        ModuleCatalog mc = Microsoft.Practices.Prism.Modularity.ModuleCatalog.CreateFromXaml(
                                    new Uri(ModuleCatalogUri, UriKind.Relative));
        return mc;
               
    }

    protected override DependencyObject CreateShell() {
        // Use the container to create an instance of the shell.
        Shell view = this.Container.TryResolve<Shell>();

        // Set it as the root visual for the application.
        Application.Current.RootVisual = view;

        return view;
    }
}

Here's the Modules catalog:

<Modularity:ModuleCatalog    
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:Modularity="clr-namespace:Microsoft.Practices.Prism.Modularity;assembly=Microsoft.Practices.Prism">
    <Modularity:ModuleInfoGroup
        Ref="Companies.xap"
        InitializationMode="WhenAvailable">
        <Modularity:ModuleInfo
            ModuleName="Companies"
            ModuleType="Companies.Companies, Companies, 
                        Version=1.0.0.0, Culture=neutral,
                PublicKeyToken=null" >
        </Modularity:ModuleInfo>
        <Modularity:ModuleInfo
            ModuleName="Countries"
            ModuleType="Countries.Countries, Countries, 
                        Version=1.0.0.0, Culture=neutral,
                PublicKeyToken=null" >
        </Modularity:ModuleInfo>
    </Modularity:ModuleInfoGroup>
</Modularity:ModuleCatalog>

Here's one of the modules's implementation classes:

public class Countries : IModule {
    private readonly IUnityContainer container;
    private readonly IRegionManager regionManager;

    public Countries(IUnityContainer container, IRegionManager regionManager) {
        this.container = container;
        this.regionManager = regionManager;
    }

    public void Initialize() {
        this.regionManager.RegisterViewWithRegion("RightRegion",
                                                    () => this.container.Resolve<CountriesView>());
    }
}

 Here's the shell:

<Grid x:Name="LayoutRoot"
        Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="250" />
        <ColumnDefinition Width="3*" />
    </Grid.ColumnDefinitions>
    <TextBlock Text="My Prism Solution"
                FontSize="36"
                TextAlignment="Left"
                HorizontalAlignment="Center"
                Grid.ColumnSpan="2" />
    <Border Grid.Row="1">
        <ContentControl x:Name="LeftRegion"
                        prism:RegionManager.RegionName="LeftRegion"
                        VerticalContentAlignment="Stretch"
                        HorizontalContentAlignment="Stretch" />
    </Border>

    <Border Grid.Column="1"
            Grid.Row="1"
            Grid.RowSpan="2">
        <ContentControl x:Name="MainRegion"
                        prism:RegionManager.RegionName="RightRegion"
                        VerticalContentAlignment="Stretch"
                        HorizontalContentAlignment="Stretch">
        </ContentControl>
    </Border>
</Grid> 

Here's the exception I get when running the app:

{Microsoft.Practices.Prism.Modularity.ModuleInitializeException: Unable to retrieve the module type Countries.Countries, Countries,                          Version=1.0.0.0, Culture=neutral,                 PublicKeyToken=null from the loaded assemblies.  You may need to specify a more fully-qualified type name.
   en Microsoft.Practices.Prism.Modularity.ModuleInitializer.HandleModuleInitializationError(ModuleInfo moduleInfo, String assemblyName, Exception exception)
   en Microsoft.Practices.Prism.Modularity.ModuleInitializer.Initialize(ModuleInfo moduleInfo)
   en Microsoft.Practices.Prism.Modularity.ModuleManager.InitializeModule(ModuleInfo moduleInfo)
   en Microsoft.Practices.Prism.Modularity.ModuleManager.LoadModulesThatAreReadyForLoad()
   en Microsoft.Practices.Prism.Modularity.ModuleManager.IModuleTypeLoader_LoadModuleCompleted(Object sender, LoadModuleCompletedEventArgs e)
   en Microsoft.Practices.Prism.Modularity.XapModuleTypeLoader.RaiseLoadModuleCompleted(LoadModuleCompletedEventArgs e)
   en Microsoft.Practices.Prism.Modularity.XapModuleTypeLoader.RaiseLoadModuleCompleted(ModuleInfo moduleInfo, Exception error)
   en Microsoft.Practices.Prism.Modularity.XapModuleTypeLoader.HandleModuleDownloaded(DownloadCompletedEventArgs e)
   en Microsoft.Practices.Prism.Modularity.XapModuleTypeLoader.IFileDownloader_DownloadCompleted(Object sender, DownloadCompletedEventArgs e)
   en Microsoft.Practices.Prism.Modularity.FileDownloader.WebClient_OpenReadCompleted(Object sender, OpenReadCompletedEventArgs e)
   en System.Net.WebClient.OnOpenReadCompleted(OpenReadCompletedEventArgs e)
   en System.Net.WebClient.OpenReadOperationCompleted(Object arg)}

If I don't load the Countries module, the same exception is thrown for the other module Companies.

Could you please tell me what am I missing here?

Developer
Jul 25, 2012 at 12:35 PM

Hi,

Based on my understanding of your scenario, I believe the problem you are experiencing is related to the way you are defining your ModuleCatalog. Based on the code snippets you provided, in your ModuleCatalog two modules from different xap files are defined in the same ModuleInfoGroup which is not allowed. And as the properties set for the group will be applied to all its contained modules,  your application will try to load both modules at startup, causing the error you mentioned.

Hence, to avoid this for example you could define the modules contained in different xap files in different ModuleInfoGroup.

As an example of this, I recommend you to check the Modularity QuickStarts for Silverlight provided with Prism.

Regards,

Agustin Adami
http://blogs.southworks.net/aadami

Jul 25, 2012 at 3:03 PM
Edited Jul 25, 2012 at 3:05 PM

I defined different xap files and it worked.

<Modularity:ModuleCatalog    
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:Modularity="clr-namespace:Microsoft.Practices.Prism.Modularity;assembly=Microsoft.Practices.Prism">
    <Modularity:ModuleInfo Ref="Companies.xap"
                      ModuleName="Companies"
                      ModuleType="Companies.Companies, Companies, Version=1.0.0.0"
                      InitializationMode="WhenAvailable" />
    <Modularity:ModuleInfo Ref="Countries.xap"
                      ModuleName="Countries"
                      ModuleType="Countries.Countries, Countries, Version=1.0.0.0"
                      InitializationMode="WhenAvailable" />
</Modularity:ModuleCatalog>

My new question is: How can I, using the ModuleCatalog.xaml, define one xap file for both modules. I tried to do it with no success. I thought that the ModuleCatalog was also useful to define the way that the modules were packed into xap files, and that by using the ModuleInfoGroup one could to do it.

Where can I instruct VS to create only one xap file for both modules?

Developer
Jul 25, 2012 at 8:50 PM

Hi,

As far as I know, a module catalog does not take part in the building process of your application and cannot be used to define how the modules are packed in your application. Based on my understanding, a module catalog is simply used by Prism to know which modules it needs to load when the application run.

As far as I know, by default each Silverlight Application Project created in your solution will be packed in a different .xap file. As the modules defined in your application are in fact Silverlight Application Projects, Visual Studio automatically pack them in different .xap files when the project is build.

As a possible workaround, you can define more than one module in the same Silverlight Application Project, as each module is simply a class implementing the IModule interface were the initialization of the module is done and a set of classes the included in the module. You would still need to define the each module in the module catalog, but they would have the same Ref attribute.

I am not aware if Visual Studio can be configured to include more that one Silverlight Application Project in the same .xap file, but as this is more related to the way Silverlight applications are built I believe you can find better support regarding this topic in the following forums:

Regards,

Damian Cherubini
http://blogs.southworks.net/dcherubini

Jul 25, 2012 at 9:25 PM

Thank you Damian.