【问题标题】:WPF Prism Module InitializationWPF Prism 模块初始化
【发布时间】:2016-03-28 00:52:07
【问题描述】:

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

问题在于了解 Prism 的工作原理。 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 类:

[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()
    {
    }
}

问题就在这里。在BootstrapperMainWindow

<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 命名空间,它会正常工作。

【问题讨论】:

    标签: c# wpf prism prism-6


    【解决方案1】:

    Prism 有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(电视机)中的什么位置显示。

    【讨论】:

    • 您的答案的第三部分不正确。 Prism 会加载它发现的任何实现 IModule 的模块,无论它们是否在区域中被调用。此外,区域只是调用视图,而不是 Module 类。请注意,我告诉 Prism 我的模块将位于 AppDomain.CurrentDomain.BaseDirectory,因此它已经知道它们存在。
    • @AzzamAziz 是的,Prism 加载 Modules 如果你在 CreateModuleCatalog 中编写代码。但是,如果没有RegionManager,Prism 不知道Module 应该在Shell 中的哪个位置显示。
    • 这很好,因为我还没有尝试展示它,我只是想确保它加载。问题不在于它没有显示。就是没有加载。
    • @AzzamAziz 模块已加载。您可以在CreateModuleCatalog 方法中使用调试器查看它。但是,当您将此代码 &lt;mainAppMock:MainUserControl /&gt; 粘贴到 Shell(TV-Set) 中时,不会注入模块的 View。 Prism 不知道 Module 在没有 RegionManager 的情况下应该在 Shell 中显示的位置
    • 不。模块未加载。这就是我问这个问题的原因。编写代码并调试它。 MainAppMock 将不会加载。
    【解决方案2】:

    在与几个人讨论后,我们得出了一个结论。

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

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

    【讨论】:

      猜你喜欢
      • 2014-01-18
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      • 1970-01-01
      • 2018-02-13
      相关资源
      最近更新 更多