Lazy loading of modules using MEF-Prism

Feb 9, 2011 at 9:49 AM
Edited Feb 9, 2011 at 11:32 AM

Hi,

I am trying to perform a lazy loading of modules using MEF-Prism. I have checked the Prism sample, on modularity. It seems that ondemand module load is something like loading a module once user performs some action.

Is it possible to load module based on internal trigger i.e. implicitly? Or do I need to provide a trigger to load the module?

I am puting a sample snippet,

 public partial class ReOBootstrapper : MefBootstrapper
    {
        protected override DependencyObject CreateShell() { return this.Container.GetExportedValue<Shell>(); }

        protected override void  InitializeShell() { base.InitializeShell(); App.Current.MainWindow = (Shell)this.Shell; App.Current.MainWindow.Show(); }
        
        protected override void ConfigureAggregateCatalog() {
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()));
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog((typeof(ModuleA).Assembly)));
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog((typeof(ModuleB).Assembly)));
        }

        protected override void ConfigureContainer() { base.ConfigureContainer();  }           
    }

This is Module A: which I want to load as it becomes available,

  [ModuleExport(typeof(ModuleA))]
    public class ModuleA: IModule
    {

[Import] private IModuleManager manager;


        public ModuleA() {   }
        public void Initialize() {

           manager.LoadModule("ModuleB");  }
    }

I want to load this module based on something (*trigger etc.*) from ModuleA (from Initialize)

  [ModuleExport("ModuleB",typeof(ModuleB),InitializationMode = InitializationMode.OnDemand)]
    public class ModuleB: IModule
    {
        public ModuleB() {   }
        public void Initialize() { // Do some intialization  }
    }

Does this look conceptually correct?

 

Feb 9, 2011 at 7:21 PM

It is entirely possible to load Modules at your discretion, however you need to bear in mind that once a module has been loaded, there is no unloading except at process termination.

        protected override void ConfigureAggregateCatalog() {
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()));
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog((typeof(ModuleA).Assembly)));
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog((typeof(ModuleB).Assembly)));
        }

what you have done here is ... you've told the MEF subsystem to load ModuleA and ModuleB, so you cannot load it again explicitly. Just remove this line ....

this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog((typeof(ModuleB).Assembly)));
and instead place it into your ModuleB's IModule implementation.

Feb 10, 2011 at 4:19 AM

Bill,

As I understand, using AggregateCatalog is possible inside the class implementing MEFBootstrapper. Will it be possible to add assemblycatalog from Module?

Plus, what is the significanse of using IModuleManager from a Module? Do I need to use a ModuleCatalog for storing Module information?

 

Any pointers/snippets highly appreciated.

Thanks,

Indro