WPF 棱镜模块初始化
WPF Prism Module Initialization
我有一个带两个模块的 Prism Shell。一个模块应该是主应用程序模拟,MainAppMock
,另一个模块应该是主系统用作区域的任何模块,ModuleOne
。可以是一个,也可以是百万个模组。
问题在于了解 Prism 的工作原理。 MainAppModule
正确初始化,除非我在 Bootstrapper
MainWindow.xaml
文件中调用它的命名空间。
我的问题:这是因为它在我调用该命名空间时 运行 加载模块,因此 Prism
没有加载它,因为它已经加载了吗?幕后究竟发生了什么?
Shell:
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 是一样的,只是名字不同。
模块一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
命名空间,它会正常工作。
Prism 有 Modules
和 Shell
。假设 Shell
是 TV-Set,因此,Modules
将是 TV-Set 中的频道。在方法 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
(电视机)中显示。
经过与几个人的讨论,我们得出了一个结论。
我们通过在 Shell
MainWindow
中调用 namespace:MainUserControl
来加载 MainAppMock
。当 Prism 的引导程序 运行s 时,它将进入 AppDomain.CurrentDomain.BaseDirectory
并在 DLL 中搜索任何继承自 IModule
的内容。它意识到 MainAppMock
这样做了,但它已经加载了。加载一个已经加载过的 DLL 是没有意义的。因此,它不会重新加载它并且 Module
永远不会 运行.
值得一提的是,MainAppMock
初始化方法是在加载DLL时运行ning。我们实际上可以在那里编写我们的 Prism Module
代码,但不推荐这样做。
我有一个带两个模块的 Prism Shell。一个模块应该是主应用程序模拟,MainAppMock
,另一个模块应该是主系统用作区域的任何模块,ModuleOne
。可以是一个,也可以是百万个模组。
问题在于了解 Prism 的工作原理。 MainAppModule
正确初始化,除非我在 Bootstrapper
MainWindow.xaml
文件中调用它的命名空间。
我的问题:这是因为它在我调用该命名空间时 运行 加载模块,因此 Prism
没有加载它,因为它已经加载了吗?幕后究竟发生了什么?
Shell:
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 是一样的,只是名字不同。
模块一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
命名空间,它会正常工作。
Prism 有 Modules
和 Shell
。假设 Shell
是 TV-Set,因此,Modules
将是 TV-Set 中的频道。在方法 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
(电视机)中显示。
经过与几个人的讨论,我们得出了一个结论。
我们通过在 Shell
MainWindow
中调用 namespace:MainUserControl
来加载 MainAppMock
。当 Prism 的引导程序 运行s 时,它将进入 AppDomain.CurrentDomain.BaseDirectory
并在 DLL 中搜索任何继承自 IModule
的内容。它意识到 MainAppMock
这样做了,但它已经加载了。加载一个已经加载过的 DLL 是没有意义的。因此,它不会重新加载它并且 Module
永远不会 运行.
值得一提的是,MainAppMock
初始化方法是在加载DLL时运行ning。我们实际上可以在那里编写我们的 Prism Module
代码,但不推荐这样做。