Prism模块未初始化

时间:2012-09-17 13:39:13

标签: module prism unity-container

我正在使用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,即使注册了视图模型,它也能正确初始化。

2 个答案:

答案 0 :(得分:1)

我担心你误解了模块类的目的。模块类用于注册模块程序集中提供的类。它仅用于基础设施目的。所以不要试图将任何业务逻辑放在模块类中。

您的断点未被命中的原因是DI容器无法解析注入的类型HelloWorldModule2ViewModel。您尝试在初始化之前使用DI容器,因此初始化过程会因异常而中止。

请查看Prism手册并仔细阅读第2章。另请参阅参考实现。

答案 1 :(得分:0)

我知道这个问题很古老,但是我碰巧尝试研究类似的问题。由于找不到很好的答案,因此希望在这里留下帮助。

我正在使用Prism和DirectoryModuleCatalog加载IModule实例,以将组件插入我的应用程序。多年来,它一直运行良好,但是当我尝试向其中一个模块添加功能时,我发现其中一个模块未加载。在Output或任何内容中无异常显示-模块不会初始化。 dll本身已加载,我可以使用其中的类,甚至可以动态访问的类。

经过大量研究,我偶然发现了一个事实,即该模块在外壳程序的配置文件中引用了一个类(用于加载自定义sql提供程序)。当我删除该引用时,模块初始化就好了。这类似于您注释掉上面从模块库中注册类型的代码。

我的结论(尚未完全验证)是,如果模块库已经加载,则DirectoryModuleCatalog或模块加载器在加载库时仅会发生反射,而无法/不会在该库上运行初始化模块。这似乎是模块加载器中的错误,尤其是因为似乎没有错误/日志生成并且它只是默默地失败了。还没有深入研究调试的Prism模块是否已加载以进行确认。

我认为我的解决方案是将自定义sql提供程序分离到一个单独的库中,尽管我认为我不必这样做。