Jamie Kurtz

Promoting architectural simplicty

  Home  |   Contact  |   Syndication    |   Login
  27 Posts | 0 Stories | 54 Comments | 5 Trackbacks

News



Archives

I’m working on a project where we are using the Composite Application Library from Microsoft’s patterns & practices team. You can read the official documentation on that site and on MSDN for all the details, but basically the CAL allows you to build applications using totally decoupled modular components – or “modules” in CAL vernacular. These modules are discovered at runtime and are registered in the CAL container, which then handles each modules’ loading, showing, unloading, etc. (I’m greatly simplifying here).

To enable runtime module discovery, you can pick between one of four different “cataloging” methods:

  • Populate from code
  • Populate from XAML
  • Populate from a configuration file
  • Populate from a directory

The fourth one, populating from a directory, is what we wanted to use. This method of cataloging allows you to drop modules into a directory and have them picked up by the CAL. Essentially, it examines all assemblies in the directory and looks for types decorated with the ModuleAttribute attribute.

The CAL’s implementation of this directory cataloging only allows for a single directory. It does this through the DirectoryModuleCatalog catalog. As taken from the CAL’s documentation, the following example will configure your application to search in a Modules subdirectory for all modules:

   1: protected override IModuleCatalog GetModuleCatalog()
   2: {
   3:     return new DirectoryModuleCatalog() {ModulePath = @".\Modules"};
   4: }

Very cool!! But… we need to search through multiple directories – not just a single directory.

Long story short, I was able to subclass the DirectoryModuleCatalog to create a new directory-based catalog that can search as many directories as you want to give it. Now, you might laugh at my new catalog, but it does work!! Here it is:

   1: /// <summary>
   2: /// Allows our shell to probe multiple directories for module assemblies
   3: /// </summary>
   4: public class MultipleDirectoryModuleCatalog : DirectoryModuleCatalog
   5: {
   6:     private readonly IList<string> _pathsToProbe;
   7:      
   8:     /// <summary>
   9:     /// Initializes a new instance of the MultipleDirectoryModuleCatalog class.
  10:     /// </summary>
  11:     /// <param name="pathsToProbe">An IList of paths to probe for modules.</param>
  12:     public MultipleDirectoryModuleCatalog(IList<string> pathsToProbe)
  13:     {
  14:         _pathsToProbe = pathsToProbe;     
  15:     }
  16:  
  17:     /// <summary>
  18:     /// Provides multiple-path loading of modules over the default <see cref="DirectoryModuleCatalog.InnerLoad"/> method.
  19:     /// </summary>
  20:     protected override void InnerLoad()
  21:     {
  22:         foreach (string path in _pathsToProbe)
  23:         {
  24:             ModulePath = path;
  25:             base.InnerLoad();
  26:         }
  27:     }
  28: }

All you need to do is provide an IList<string> of paths – that’s it! So, to update the CAL’s sample:

   1: protected override IModuleCatalog GetModuleCatalog()
   2: {
   3:     IList<string> pathsToProbe = GetPathsToProbe();
   4:     return new MultipleDirectoryModuleCatalog(pathsToProbe);
   5: }
posted on Tuesday, January 26, 2010 9:25 AM

Feedback

# re: Composite Application Library (“PRISM”) and loading modules from multiple directories 3/12/2010 7:20 PM Benjamin
Here is an improvement to the original DirectoryModuleCatalog that searches all sub directories of the ModulePath

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

DirectoryInfo[] directoryInfoArray = new DirectoryInfo(ModulePath).GetDirectories("*.*", SearchOption.AllDirectories);

foreach (DirectoryInfo directoryInfo in directoryInfoArray)
{
ModulePath = directoryInfo.FullName;
base.InnerLoad();
}
}

# re: Composite Application Library (“PRISM”) and loading modules from multiple directories 3/14/2010 9:07 PM Jamie
Great, thanks! Good idea.

Post A Comment
Title:
Name:
Email:
Comment:
Verification: