PRISM和WPF如何按需添加模块

PRISM and WPF how to add a module on demand

我的shell窗口中有一组选项卡,而一个主要区域whicxh是contentcontrol。 当选择某个选项卡时,我还想按需加载四个模块。 因此,当选择tab1时,我要加载模块A,当选择tab2时,我要加载模块B,等等。第一个模块在应用程序启动时加载。 问题是,当我更改选项卡时,什么也没有发生。 没有艰难的错误。 我正在使用此版本的WPF和Silverlight棱镜综合应用指南-2009年10月。

我尝试了这种方法:

贝壳:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 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");
        }
}

引导程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  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;
    }

}

我希望能够按需加载的moduleB(我曾经使用此注释行,这就是为什么我将其留在这里的原因):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[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>();
    }
}

我在这里做错了什么? 我应该如何进行?


我成功使用了按需加载模块。在我的情况下,我在用户登录后加载它们。

为了对项目进行完整性检查,请确保ModuleB.dll与Shell /应用程序位于同一目录中。 (例如,如果您处于调试模式,请确保将其复制到调试目录)。

我有相同的模块名称和模块dll,我不确定这是否是必需项,但是我一直坚持的约定。

我的引导程序CreateModuleCatalog非常简单

1
2
3
4
5
6
protected override IModuleCatalog CreateModuleCatalog()
{
    ModuleCatalog catalog = new ConfigurationModuleCatalog();
    return catalog;

}

模块列在我的app.config文件中

1
2
3
<modules>
    <module assemblyFile="PatronModule.dll" moduleType="PatronModule.PatronModuleDefinition, PatronModule" moduleName="PatronModule" startupLoaded="false" />
</modules>

然后当我加载模块时我使用此代码

1
2
3
4
    IModuleManager moduleManager = _container.Resolve<IModuleManager>();
    ModulesConfigurationSection modules = ConfigurationManager.GetSection("modules") as ModulesConfigurationSection;
    foreach (ModuleConfigurationElement module in modules.Modules)
        moduleManager.LoadModule(module.ModuleName);

模块的加载必须在GUI线程上进行,因此,如果需要,您需要使用分派器进行加载(这是我使用的行)

1
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle, new Action(() => { LoadModulesOnGuiThread(); }));

希望这可以帮助


我不太确定,但是尝试在添加模块时将InitializationMode设置为OnDemand,如下所示:

1
2
var catalog = new ModuleCatalog();
catalog.AddModule(typeof(ModuleA)).AddModule(typeof(ModuleB), InitializationMode.OnDemand);