This code won’t work in a Prism bootstrapper:
1: protected override IModuleCatalog GetModuleCatalog()
2: {
3: ModuleCatalog NewModuleCatalog = new ModuleCatalog();
4: NewModuleCatalog.AddModule(typeof(JeffFerguson.Narrative.Wpf.Units.Module));
5: NewModuleCatalog.AddModule(typeof(JeffFerguson.Narrative.Wpf.XbrlDocumentLoader.Module));
6: return NewModuleCatalog;
7: }
If you run code like this, Prism will throw an exception of type DuplicateModuleException with a message that reads “A duplicated module with name Module has been found by the loader.”.
The issue is that Prism uses module names to distinguish one module for another, and, by default, the class name is used as the module name when a module name is not specified. Since, according to Prism (and much to my chagrin), only the tail end of the class name is used when constructing module names, there are, according to Prism, two classes named Module in the code snippet above.
Fortunately, this is all easily fixed through the use of a ModuleInfo object, where all of the information about a module can be specified and added to a module catalog as a unit. My bootstrapper code looks (in part) like this:
1: protected override IModuleCatalog GetModuleCatalog()
2: {
3: ModuleCatalog NewModuleCatalog = new ModuleCatalog();
4: AddModuleToCatalog(typeof(JeffFerguson.Narrative.Wpf.Units.Module), NewModuleCatalog);
5: AddModuleToCatalog(typeof(JeffFerguson.Narrative.Wpf.XbrlDocumentLoader.Module), NewModuleCatalog);
6: return NewModuleCatalog;
7: }
8:
9: private void AddModuleToCatalog(Type ModuleType, ModuleCatalog Catalog)
10: {
11: ModuleInfo NewModuleInfo = new ModuleInfo();
12: NewModuleInfo.ModuleName = ModuleType.AssemblyQualifiedName;
13: NewModuleInfo.ModuleType = ModuleType.AssemblyQualifiedName;
14: Catalog.AddModule(NewModuleInfo);
15: }
This code simply uses the module type’s assembly qualified name, which will be unique throughout the application, as the name of the module.
My rant here is that I believe Prism should be using the value of the module type’s AssemblyQualifiedName property, and not just the Name property, by default as the module’s name. The two types in the original example are uniquely named, since the class’ namespace forms a part of its fully qualified name. If I had to name my two Module classes with unique tail names (like “UnitsModule” and “XbrlDocumentLoaderModule”, for example), then I wouldn’t have much need for a unique namespace.
OK. Rant over.