I have a set of tabs in my shell window and one main region whicxh is a contentcontrol. I also have four modules that I want to load on demand when a certain tab is selected. So when tab1 is selected I want to load moduleA, when tab2 is selected I want to load ModuleB, etc. The first module loads on when the application starts. The problem is that when I change the tab nothing happens. There are no errors tough. I'm using this version of prism Composite Application Guidance for WPF and Silverlight - October 2009.
I tried this approach:
Shell:
public partial class Shell : RibbonWindow, IShellView
{
private readonly IRegionManager regionManager;
private readonly IModuleManager moduleManager;
public Shell(IModuleManager moduleManager)
{
this.moduleManager = moduleManager;
InitializeComponent();
}
public void ShowView()
{
this.Show();
}
private void onTabSelection(object sender, RoutedEventArgs e)
{
this.moduleManager.LoadModule("ModuleB");
}
}
Bootstrapper:
public partial class MyBootstrapper : UnityBootstrapper
{
protected override IModuleCatalog GetModuleCatalog()
{
var catalog = new ModuleCatalog();
catalog.AddModule(typeof(ModuleA)).AddModule(typeof(ModuleB));
return catalog;
}
protected override void ConfigureContainer()
{
Container.RegisterType<IShellView, Shell>();
base.ConfigureContainer();
}
protected override DependencyObject CreateShell()
{
ShellPresenter presenter = Container.Resolve<ShellPresenter>();
IShellView view = presenter.View;
view.ShowView();
return view as DependencyObject;
}
}
And moduleB that I want to be able to load on demand (I used to use this commented line that's why I left it here):
[Module(ModuleName = "ModuleB", OnDemand = true)]
public class ModuleB : IModule
{
private readonly IUnityContainer _container;
private readonly IRegionManager _regionManager;
public ModuleB(IUnityContainer container, IRegionManager regionManager)
{
_container = container;
_regionManager = regionManager;
}
public void Initialize() {
_regionManager.Regions["MainRegion"].Add(new ModuleBView());
this.RegisterViewsAndServices();
// this._regionManager.RegisterViewWithRegion(RegionNames.MainRegion, () => _container.Resolve<MissionProfileView>());
}
protected void RegisterViewsAndServices()
{
_container.RegisterType<Modules.ModuleBView>();
}
}
What am I doing wrong here? How should I proceed?
i am successfully using ondemand loading of modules. in my scenario, i load them after the user logs in.
As a sanity check with your project, ensure that your ModuleB.dll is in the same directory as your shell/application. ( for instance make sure it gets copied to the debug directory if you are in debug mode ).
I have the module name and the module dll named the same, i am not sure if this is a requirement, but its the convention that i have stuck with.
my bootstrappers CreateModuleCatalog is very simple
protected override IModuleCatalog CreateModuleCatalog()
{
ModuleCatalog catalog = new ConfigurationModuleCatalog();
return catalog;
}
the modules are listed in my app.config file
<modules>
<module assemblyFile="PatronModule.dll" moduleType="PatronModule.PatronModuleDefinition, PatronModule" moduleName="PatronModule" startupLoaded="false" />
</modules>
then when i load the modules i use this code
IModuleManager moduleManager = _container.Resolve<IModuleManager>();
ModulesConfigurationSection modules = ConfigurationManager.GetSection("modules") as ModulesConfigurationSection;
foreach (ModuleConfigurationElement module in modules.Modules)
moduleManager.LoadModule(module.ModuleName);
The loading of modules has to happen on the GUI thread, so if required you need to use the dispatcher to do the loading ( this is the line i use for it )
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle, new Action(() => { LoadModulesOnGuiThread(); }));
hope this helps