我正在使用Prism和Unity创建一个应用程序。我使用DirectoryModuleCatalog
从磁盘加载多个模块,这些模块显示在主菜单中,当您单击此特定模块的名称时,将加载此模块的UI。
每个模块都是根据MVVM模型设计的,因此使用单独的视图和视图模型。
引导程序:
class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
Shell shell = Container.Resolve<Shell>();
shell.Show();
return shell;
}
protected override void InitializeShell()
{
base.InitializeShell();
App.Current.MainWindow = (Window)this.Shell;
App.Current.MainWindow.Show();
}
protected override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType<IApplicationMenuRegistry, MenuRegistry>();
Container.RegisterType<IApplicationCommands, ApplicationCommands>();
Container.RegisterType<ShellViewModel, ShellViewModel>(new Microsoft.Practices.Unity.ContainerControlledLifetimeManager());
//****** When I uncomment following line, the HelloWorldModule2 doesn't get initialized ***********
// Container.RegisterType<HelloWorldModule2ViewModel, HelloWorldModule2ViewModel>(new Microsoft.Practices.Unity.ContainerControlledLifetimeManager());
}
protected override IModuleCatalog CreateModuleCatalog()
{
return new DirectoryModuleCatalog() { ModulePath = @"C:\Data\NPC Service Tool\Source\develop\POC\GUIWithPrism\Modules" };
}
}
模块:
namespace HelloWorldModule2
{
[Module(ModuleName="HelloWorldModule2")]
public class HelloWorldModule2 : IModule
{
private IApplicationMenuRegistry menuRegistry;
private HelloWorldModule2ViewModel viewModel;
private IRegionManager regionManager;
public HelloWorldModule2(IApplicationMenuRegistry menuRegistry, HelloWorldModule2ViewModel vm, IRegionManager regionManager)
{
this.menuRegistry = menuRegistry;
this.regionManager = regionManager;
this.viewModel = vm;
}
public void Initialize()
{
ObservableCollection<ViewObject> views = new ObservableCollection<ViewObject>();
views.Add(new ViewObject() { Region = RegionName.Right, ViewType = typeof(HelloWorld2View) });
views.Add(new ViewObject() { Region = RegionName.Left, ViewType = typeof(View2) });
//****** Here the module gets registered in the main menu ******//
menuRegistry.RegisterModuleMenuItem("HelloWorld2", "Hello World module 2",views,1);
this.viewModel.Title = "Hello world module 2";
}
}
}
查看型号:
namespace HelloWorldModule2.ViewModels
{
public class HelloWorldModule2ViewModel : NotificationObject
{
private string title;
public string Title
{
get { return title; }
set
{
title = value;
RaisePropertyChanged(() => this.Title);
}
}
}
}
我遇到了以下问题:
当我在Unity容器中注册视图模型时,如Bootstrapper代码中所示,我的模块没有初始化(我在模块的Initialize
方法中设置了一个断点,但它永远不会
命中)。如果我删除了注册并删除了模块构造函数中的vm参数,则模块会进行初始化。
当我使用以下模块手动配置模块目录时:
protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();
ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
moduleCatalog.AddModule(typeof(HelloWorldModule2.HelloWorldModule2));
}
而不是DirectoryModuleCatalog
,即使注册了视图模型,它也能正确初始化。
答案 0 :(得分:1)
我担心你误解了模块类的目的。模块类用于注册模块程序集中提供的类。它仅用于基础设施目的。所以不要试图将任何业务逻辑放在模块类中。
您的断点未被命中的原因是DI容器无法解析注入的类型HelloWorldModule2ViewModel。您尝试在初始化之前使用DI容器,因此初始化过程会因异常而中止。
请查看Prism手册并仔细阅读第2章。另请参阅参考实现。
答案 1 :(得分:0)
我知道这个问题很古老,但是我碰巧尝试研究类似的问题。由于找不到很好的答案,因此希望在这里留下帮助。
我正在使用Prism和DirectoryModuleCatalog加载IModule实例,以将组件插入我的应用程序。多年来,它一直运行良好,但是当我尝试向其中一个模块添加功能时,我发现其中一个模块未加载。在Output或任何内容中无异常显示-模块不会初始化。 dll本身已加载,我可以使用其中的类,甚至可以动态访问的类。
经过大量研究,我偶然发现了一个事实,即该模块在外壳程序的配置文件中引用了一个类(用于加载自定义sql提供程序)。当我删除该引用时,模块初始化就好了。这类似于您注释掉上面从模块库中注册类型的代码。
我的结论(尚未完全验证)是,如果模块库已经加载,则DirectoryModuleCatalog或模块加载器在加载库时仅会发生反射,而无法/不会在该库上运行初始化模块。这似乎是模块加载器中的错误,尤其是因为似乎没有错误/日志生成并且它只是默默地失败了。还没有深入研究调试的Prism模块是否已加载以进行确认。
我认为我的解决方案是将自定义sql提供程序分离到一个单独的库中,尽管我认为我不必这样做。