Prism is unable to retrieve my Modules

Jul 28, 2012 at 3:52 PM
Edited Jul 28, 2012 at 4:15 PM

I don't find the reason why Prism is unable to retrieve my modules. I'll appreciate you help me with this.

I keep getting this ModuleInitializeException saying that Prism is unable to retrieve Countries.CountriesModule, and the same exception is issued with the other module Customers.

I'm using Silverlight 5, Prism 4.1.

The structure of the project is:

The ModulesCatalog is:

<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="Customers.xap"
                      ModuleName="Customers"
                      ModuleType="Customers.CustomersModule, CustomersModule, Version=1.0.0.0"
                      InitializationMode="WhenAvailable" />
    <Modularity:ModuleInfo Ref="Countries.xap"
                      ModuleName="Countries"
                      ModuleType="Countries.CountriesModule, CountriesModule, Version=1.0.0.0"
                      InitializationMode="WhenAvailable" />
</Modularity:ModuleCatalog>

The CountriesModule:

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

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

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

The Shell:

<Grid x:Name="LayoutRoot"
        Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="700" />
        <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>

The Bootstrapper:

public class MyBootstrapper : UnityBootstrapper {
    private const string ModuleCatalogUri =
                            "/NewPrismSolution;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;
    }
}

I sense that the problem is in the ModulesCatalog, but I can't figure out what it is.

Need your help here...

My best regards.

Rafael

Jul 30, 2012 at 1:10 AM

Hi:

I fixed the problem by setting the same name to the Module itself and to the implementator class:  

<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="CustomersModule.xap"
                           ModuleName="CustomersModule"
                           ModuleType="CustomersModule.CustomersModule, CustomersModule, Version=1.0.0.0, Culture=neutral,
                PublicKeyToken=null">
    </Modularity:ModuleInfo>
    <Modularity:ModuleInfo Ref="CountriesModule.xap"
                           ModuleName="CountriesModule"
                           ModuleType="CountriesModule.CountriesModule, CountriesModule, Version=1.0.0.0, Culture=neutral,
                PublicKeyToken=null">
    </Modularity:ModuleInfo>
</Modularity:ModuleCatalog>

For instance, one module's name is CustomersModule, and the implementator class is named CustomersModule:

Is that it?, do they have to have the same name?, I remember developing a solution that didn't have the same name, but used MEF instead of Unity...

Developer
Jul 30, 2012 at 3:14 PM

Hi Rafael,

Based on my experience, they necessarily don't need to have the same name. I believe, the error you received the first time could be caused by the way you  defined your ModuleInfo classes in your ModuleCatalog, in particular the ModuleType property. For example I believe they could be changed like this:

<Modularity:ModuleInfo Ref="Customers.xap"
                      ModuleName="Customers"
                      ModuleType="Customers.CustomersModule, Customers, Version=1.0.0.0"
                      InitializationMode="WhenAvailable" />

Note that, in this code snippet I change the ModuleType second argument from CustomersModule to Customers. Which, should be your module's namespace and not your module's type.

I hope you find this handy,

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

Jul 30, 2012 at 6:59 PM
Edited Jul 30, 2012 at 7:09 PM

Hi Agustin:

If we have:

ModuleType="<param A>, <param B>, Version=1.0.0.0, Culture=neutral,
                PublicKeyToken=null">

What do "param A" and "param B" mean exactly?

Developer
Jul 30, 2012 at 8:11 PM

Hi Rafael,

Based on my understanding, when defining a module catalog the ModuleType attribute accepts a string representing the AssemblyQualifiedName of the module class.

For example, if we have a module in an assembly named "ModuleAssembly," which contains an IModule class "ModuleClass" inside the namespace "ModuleNamespace," then:

  • <param A> is the full name of the IModule class: namespace.class. In this example, it would be ModuleNamespace.ModuleClass.
  • <param B> is the name of the assembly. In this example, it would be ModuleAssembly.

The ModuleType would then look like this:

ModuleType="ModuleNamespace.ModuleClass, ModuleAssembly, Version=1.0.0.0"

You can find more information about the AssemblyQualifiedName in the following MSDN article:

I hope you find this useful,

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

Jul 31, 2012 at 3:36 AM

Thank you Damian for the Information.