棱镜:在创建shell后将模块加载到目录中

时间:2011-03-01 04:27:52

标签: wpf unity-container prism mef

使用Unity或MEF可以在引导程序创建目录后加载模块吗?换句话说,有一个按钮单击加载一个模块,该模块在应用程序启动时已知,并且引导程序CreateModuleCatalog代码已执行?我没有在文档中或通过互联网搜索找到一个很好的例子。要么它不支持这个,要么我只是缺少一些东西。我找到的所有东西都只在bootstapper中加载模块。

我试图做概念验证的基本WPF项目是:

  1. 加载应用程序。它将加载一些标准模块。 shell将被创建并可见。
  2. 用户交互将触发发现新模块的需要,将其添加到目录中,然后在UI上公开。我不太关心它如何发现模块,更重要的是如何加载它们。该发现很可能是查询数据库,下载所需的.dll然后保存到已知目录。
  3. 我有一种感觉,它相对简单,而我一直在旋转我的车轮试图解决这个问题。

2 个答案:

答案 0 :(得分:3)

看一下Prism 4.0 Quickstart - 使用MEF for Silverlight进行模块化。

此快速入门从XAML创建目录,但您可以手动将条目添加到模块目录并传递类似的参数。模块信息类唯一需要的是XAP文件的REF。

您还可以查看桌面版本。这个找到包含目录中的模块的DLL,然后从磁盘加载它们。您可以通过指向某个文件位置的已知DLL来执行相同的操作。

基本上,如果您将正确的模块信息添加到ModuleCatalog中,则需要加载模块,下载或加载DLL,并且MEF / Unity容器将初始化该模块。

答案 1 :(得分:1)

我是Prism的新手,我遇到过类似的问题。经过多次搜索,我找不到任何直接的帮助。但是,我以不同的方式解决了这个问题。以下是代码:

  1. 在viewmodel类(MasterViewModel)中创建了一个DelegateCommand属性,并在事件处理程序代码中添加并加载了Modulecatalog中的新模块。

  2. 将它连接到View的xaml上的按钮点击事件

    <Button Content="Button" Height="28" HorizontalAlignment="Left" Margin="8,0,0,0"
        Name="btnLoadModule2" VerticalAlignment="Top" Width="98" 
        prism:Click.Command="{Binding  DataContext.LoadModule2Command, ElementName=root}"/>
    
  3. 使用依赖注入来获取ModuleCatalog&amp;的引用。 ModuleManager会

  4. 在点击事件代码中,我将代码中的模块(即Module2)添加到ModuleCatalog中,并使用模块管理器加载它。

    public MasterViewModel(IDataService dataService, IEventAggregator eventAggregator, IRegionManager regionManager
                            , IModuleCatalog moduleCatalog, IModuleManager moduleManager)
    {
        _dataService = dataService;
        _eventAggregator = eventAggregator;
        _regionManager = regionManager;
    
        // Get the data model from the data service.
        _model = dataService.GetModel();
    
        // Initialize the CollectionView for the underlying model.
        DataItemsCV = new ListCollectionView(_model);
        // Track the current selection.
        DataItemsCV.CurrentChanged += new EventHandler(SelectedItemChanged);
    
        // Initialize the commands.
        NavigateToViewCommand = new DelegateCommand<string>(NavigateToView);
        SyncViewCommand = new DelegateCommand<string>(SyncView);
    
        LoadModule2Command = new DelegateCommand<string>(LoadModule2);
        _moduleCatalog = moduleCatalog;
        _moduleManager = moduleManager;
    }
    
    void LoadModule2(string s)
    {      
        ModuleInfo module = new ModuleInfo()
                            { 
                                Ref="Module2.dll", ModuleName="Module2", 
                                ModuleType="Module2.ModuleInit, Module2, Version=1.0.0.0", 
                                InitializationMode= InitializationMode.WhenAvailable , 
                             };
        module.DependsOn.Add("Module1");
    
        _moduleCatalog.AddModule(module);
        _moduleManager.LoadModule("Module2");
    
    }
    
  5. 此技术可用于在初始Shell初始化后加载模块。我必须承认,杰夫的回答有点无关紧要。