2014-01-24 39 views
2

我在PRISM中实现应用程序,需要从dll文件动态导入模块。 我设法做到了 - 他们正在导入,但我无法显示它。 我决定创建一个特殊的模块来封装它 - 让我们称之为ModuleDock。 因此,我们有这样的事情:在棱镜模块内显示棱镜模块

Bootstrapper.cs:

class Bootstrapper : UnityBootstrapper 
{ 
    protected override DependencyObject CreateShell() 
    { 
     return Container.Resolve<Shell>(); 
    } 

    protected override void InitializeShell() 
    { 
     base.InitializeShell(); 

     Application.Current.MainWindow = (Window)Shell; 
     Application.Current.MainWindow.Show(); 
    } 

    protected override IModuleCatalog CreateModuleCatalog() 
    { 
     var modules = new DirectoryModuleCatalog 
     { 
      LoadSubdirectories = true, 
      ModulePath = @"C:\Modules" 
     }; 

     modules.AddModule(typeof(ModuleDockModule)); 

     return modules; 
    } 
} 

Shell.xaml:

<ContentControl regions:RegionManager.RegionName="ModuleDockModule" /> 

ModuleDockModule.cs(在ModuleDock项目):

public class ModuleDockModule : IModule 
{ 
    private readonly IRegionManager _regionManager; 
    private readonly IUnityContainer _unityContainer; 

    public void Initialize() 
    { 
     RegisterIoc(); 
     if (_regionManager.Regions.ContainsRegionWithName("ModuleDockModule")) 
     { 
      _regionManager.RegisterViewWithRegion("ModuleDockModule", typeof(ModuleDockView)); 
     } 
    } 

    public ModuleDockModule(IRegionManager regionManager, IUnityContainer unityContainer, IRegionViewRegistry regionViewRegistry) 
    { 
     _regionManager = regionManager; 
     _unityContainer = unityContainer; 
    } 

    private void RegisterIoc() 
    { 
     _unityContainer.RegisterType<IModuleDockView, ModuleDockView>(); 

     _unityContainer.RegisterType<IModuleDockViewModel, ModuleDockViewModel>(); 
    } 

}

和加载模块的最后一个:

[Module(ModuleName = "TestModule", OnDemand = false)] 
public class TestModuleModule : IModule 
{ 
    private readonly IRegionManager _regionManager; 
    private readonly IUnityContainer _unityContainer; 

    public void Initialize() 
    { 
     RegisterIoc(); 
     if (_regionManager.Regions.ContainsRegionWithName("TestModule")) 
     { 
      _regionManager.RegisterViewWithRegion("TestModule", typeof(TestView)); 
     } 
    } 

    public TestModuleModule(IRegionManager regionManager, IUnityContainer unityContainer) 
    { 
     _regionManager = regionManager; 
     _unityContainer = unityContainer; 
    } 

    private void RegisterIoc() 
    { 
     _unityContainer.RegisterType<ITestView, TestView>(); 

     _unityContainer.RegisterType<ITestViewModel, TestViewModel>(); 
    } 
} 

出于测试目的,我创建了行XAML的:

<ContentControl regions:RegionManager.RegionName="TestModule" /> 

你能告诉我,为什么这行显示TestModule在Shell.xaml ,但不要在ModuleDockView.xaml中显示它?

请记住,在最后阶段,我必须使用不同的号码通过我的平台的其他用户提供的未知的模块,所以我不能做任何事情静态(如模块名称或初始化)。 提前谢谢!

+0

为了确认,你问为什么TestModule不ModuleDockView显示,而是在外壳?这将取决于您在哪个Xaml页面中使用内容Control定义该区域。关于静态初始化,它们将在每个模块内进行。所以你不需要担心这一点。我认为做一个枚举类定义的默认RegionNames其中每个人都知道他们的。 – GOstrowsky

+0

@GOstrowsky - no。TestModule没有显示在ModuleDockView中 - 但我知道加载它的一切都是正确的,因为如果我将相同的区域放在Shell.xaml中,并将其从ModuleDockView.xaml中移除(出于测试目的),它就会显示出来。 从其他方面 - 我使用的类与静态字符串的区域名称,但对于堆栈我为了更好的可读性使用文本值的示例。 – Zozo

+1

谢谢你的解释。问题将出现在Module的加载顺序上,因为*** TestModule ***依赖于*** ModuleDockModule ***区域的*** ModuleDockModule ***。你可以检查*** TestModule ***是否正在初始化*** ModuleDockModule ***之前?如果是这样,那么您需要在模块名称属性下添加一个依赖项属性到*** TestModuleModule ***类中,作为** [ModuleDependency(“ModuleDockModule”)] **。问候。 – GOstrowsky

回答

4

根据您所描述的代码时,TestModule模块具有ModuleDockModule,因为这是定义了TestModule的意见将被登记入区的模块依赖。

因此,你需要确保ModuleDockModule之前TestModule这将依赖于它的任何其他模块进行初始化。为了做到这一点,你就需要在TestModuleModule类中声明的依赖属性,正确的类定义的上方,如下所示:

[Module(ModuleName = "TestModule", OnDemand = false)] 
[ModuleDependency("ModuleDockModule")] 
public class TestModuleModule : IModule 
{ ... 

有关为模,你可以参考以下MSDN棱镜指南的详细信息章:

我希望这有助于你的问候。