Adding new modules to catalog inside another module init?

Jan 14, 2009 at 1:09 AM
Let's say an application uses static loading of module and adds module A to the ModuleCatalog in GetModuleCatalog.  Module A happens to use module B inside of itself.  Is there a way inside module A's Initialize method for it to say "oh, hey, if the application hasn't already installed module B into the catalog, do it and initialize it now"?

That way consumers of module A don't have to have any idea what modules A uses.  They just link to the assemblies we provide and add the modules they directly use to the catalog and that is that.  Or do we always need to tell them that even though they have no idea what module B is, they must add it to the catalog anyway and if they forget, things might not work?
Jan 14, 2009 at 12:48 PM
Edited Jan 14, 2009 at 12:58 PM

Hi

 

The default way to set a dependency between modules to make sure a specific module is loaded before another one does using static module loading could be the following one (with your sample module names):

protected override IModuleCatalog GetModuleCatalog()

        {

            var catalog = new ModuleCatalog();

            catalog.AddModule(typeof(ModuleB))

                  .AddModule(typeof(ModuleA), "ModuleB");

 

            return catalog;

        }

 

Remember that it is important that modules have no knowledge of each other to maintain the application loosely coupled, and making ModuleA know where ModuleB is deployed would be against this. Perhaps you could implement this as an assembly reference instead of a Module dependency, by creating separate projects an referencing the one with ModuleB’s functionality from ModuleA but remaining as a single module to your application.

 

However, if you still want to add new modules without changing the bootstrapper’s GetModuleCatalog() method, and don’t want to expose the dependency between Modules A and B I will explain how to do this below. You should also be aware that this will create a strong couple of the module to the CAL’s interfaces’ implementations.

To do this you can add the following code in Module A’s Inititialize() method:

 

ModuleCatalog catalog = this.container.Resolve<IModuleCatalog>() as ModuleCatalog;

if (catalog != null)

{

catalog.AddModule("ModuleB", typeof(ModuleB).AssemblyQualifiedName, InitializationMode.OnDemand);

                IModuleManager moduleManager = this.container.Resolve<IModuleManager>();

                if (moduleManager != null)

                {

                              moduleManager.LoadModule("ModuleB");

                }

}

 

For more information about module loading you can check:

·         StaticModuleLoading Quickstart

·         How to: Load Modules On Demand (documentation)

·         How to: Statically Load Modules (documentation)

 

Please let me know if this helps.

 

Damian Schenkelman

http://blogs.southworks.net/dschenkelman

 

 

 

 

Jan 14, 2009 at 2:53 PM
Thanks.  Your response was helpful.  I am aware of how the typical static loading works and have been using it.  It was just the module inside a module, where only the module knew it used another module inside of itself (when the application didn't).  I wasn't sure how one would deal with.

I will have to think about your comment about a module not having any other knowledge of another module.  Understandably a module's usage is via the interfaces it exposes, and I wasn't planning on changing that fact.  But to get the interfaces, a module has to be loaded.  So at some level, even if it is at the highest App level, they have to get tied together somehow.  Essentially what you are saying is that it should be up to the application to determine which module should be used to provide a given interface.  But how does the container find the interface if such a module wasn't loaded?  (Rhetorical question)  :)

So it comes down to a philisophical question of sorts I suppose.  Always something to think about.  And maybe I should tinker a bit with dynamic loading.