WPF棱镜模块初始化

时间:2016-03-28 00:52:07

标签: c# wpf prism prism-6

我有一个带有两个模块的Prism Shell。一个模块应该是主应用程序模拟MainAppMock,而另一个模块应该是主系统用作区域的任何模块ModuleOne。可能是一个,可能是一百万个模块。

问题在于理解棱镜是如何工作的。 MainAppModule正确初始化,除非我在Bootstrapper MainWindow.xaml文件中调用它的命名空间。

我的问题:这是因为它在运行时调用该命名空间时正在加载模块,因此Prism因为已经加载而没有加载它吗?幕后实际发生了什么?

外壳:

class Bootstrapper : NinjectBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return Kernel.Get<MainWindow>();
    }

    protected override void InitializeShell()
    {
        Application.Current.MainWindow = (Window)Shell;
        Application.Current.MainWindow.Show();
    }

    protected override IModuleCatalog CreateModuleCatalog()
    {
        return new DirectoryModuleCatalog
        {
            ModulePath = AppDomain.CurrentDomain.BaseDirectory
        };
    }
}
除了名称外,

MainAppMock和ModuleOne是相同的。

ModuleOne Class:

[Module(ModuleName = "ModuleOne.Module")]
public class Module : IModule
{
    private readonly IRegionManager _regionManager;
    private readonly IKernel _kernel;

    public Module(IRegionManager regionManager, IKernel kernel)
    {
        _regionManager = regionManager;
        _kernel = kernel;
    }

    public void Initialize()
    {
    }
}

问题出在这里。在Bootstrapper MainWindow

<Window x:Class="PrismTest.MainWindow"
    xmlns:mainAppMock="clr-namespace:MainAppMock;assembly=MainAppMock"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <mainAppMock:MainUserControl />
</Grid>

注意:如果我删除上面提到的mainAppMock命名空间,它可以正常工作。

2 个答案:

答案 0 :(得分:1)

棱镜有ModulesShell。让我们想象Shell是电视剧,因此,Modules将是电视剧中的频道。在protected override IModuleCatalog CreateModuleCatalog()方法的节目开始时(您打开电视机),您正在加载Modules(电视机加载您搜索到的频道):

protected override IModuleCatalog CreateModuleCatalog()
{
   ModuleCatalog catalog = new ModuleCatalog();
   catalog.AddModule(typeof(ModuleZooModule));//Channel about Zoo
   catalog.AddModule(typeof(ModuleSportModule));//Channel about Sport
   catalog.AddModule(typeof(ModuleProgrammingModule));//Channel about Programming
   return catalog;
}

通常Shell应如下所示:

<DockPanel >            
   <ContentControl Margin="5"
        prism:RegionManager.RegionName="{x:Static inf:RegionNames.ContentRegion}"
        prism:RegionManager.RegionManager="{Binding RegionManager}"/>
</DockPanel>

prism:RegionManager.RegionName="{x:Static inf:RegionNames.ContentRegion}"Prism显示Module(频道的视频流)应该在Shell(电视机)中注入。

但在你的情况下没有资格使用这些东西:

<Grid>
    <mainAppMock:MainUserControl />
</Grid>

由于Prism无法知道Module(电视机)中Shell(某个频道)的显示位置。

答案 1 :(得分:1)

与少数人讨论后,我们得出了一个结论。

我们通过在MainAppMock namespace:MainUserControl中调用Shell来加载MainWindow。当Prism的引导程序运行时,它将进入AppDomain.CurrentDomain.BaseDirectory并在DLL中搜索从IModule继承的任何内容。它意识到MainAppMock会这样做,但它已经加载了。加载已加载的DLL没有意义。因此,它不会重新加载它,Module永远不会运行。

值得一提的是,加载DLL时正在运行MainAppMock初始化方法。我们实际上可以在那里执行Prism Module代码,但不建议这样做。