Prism:创建 shell 后将模块加载到目录中

发布于 2024-10-19 16:28:54 字数 395 浏览 6 评论 0原文

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

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

  1. 加载应用程序。它将加载一些标准模块。 shell 将被创建并可见。
  2. 用户交互将触发发现新模块的需求,将其添加到目录中,然后将其公开在 UI 上。我不太关心它如何发现模块,更关心如何加载它们。该发现很可能是查询数据库,下载所需的 .dll,然后保存到已知目录。

我有一种感觉,它相对简单,我一直在努力想弄清楚这一点。

Using either Unity or MEF can you load Modules after the bootstrapper creates the catalog? In other words have a button click load a module which was not known when the application started and the bootstrapper CreateModuleCatalog code has executed? I have not found a good example of this either in the documentation or through internet searches. Either it does not support this or I am just plain missing something. Everything I find loads up modules in the bootstapper only.

The basic WPF project I am trying to do a proof of concept is:

  1. Load up the application. It will load up some standard modules. The shell will be created and visible.
  2. User interaction will trigger the need to discover a new module, add it to the catalog and then expose it on the UI. I am not so concerned about how it discovers the modules yet, more so on how to load them. The discovery will mostly likely be querying a database, downloading required .dlls and then saving to a known directory.

I have a feeling that it is relatively simple and I have just been spinning my wheels trying to figure this out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

逆光飞翔i 2024-10-26 16:28:54

查看 Prism 4.0 快速入门 - Silverlight 的 MEF 模块化。

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

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

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

Take a look at the Prism 4.0 Quickstart - Modularity with MEF for Silverlight.

This quickstart creates a catalog from XAML, but you can manually add entries to the module catalog and pass similar parameters. The only thing the module info class needs is the REF to the XAP file.

You can also look at the desktop version. This one finds DLLs containing modules in a directory and then loads them from disk. You could do the same thing by pointing to a known DLL at some file location.

Essentially, if you add the right module info into the ModuleCatalog, then demand loading of the module the DLL with be downloaded or loaded and MEF/Unity containers will have that module intialized.

紫瑟鸿黎 2024-10-26 16:28:54

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

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

  2. 将其挂接到视图的 xaml 上按钮的单击事件

    <按钮内容=“按钮”高度=“28”Horizo​​ntalAlignment=“左”边距=“8,0,0,0”
        名称=“btnLoadModule2”垂直对齐=“顶部”宽度=“98” 
        prism:Click.Command="{Binding DataContext.LoadModule2Command, ElementName=root}"/>
    
  3. 使用依赖项注入来获取 ModuleCatalog 和 ModuleCatalog 的引用。 ModuleManager

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

    public MasterViewModel(IDataService dataService, IEventAggregator eventAggregator, IRegionManager regionManager
                            、IModuleCatalog 模块目录、IModuleManager 模块管理器)
    {
        _dataService = 数据服务;
        _eventAggregator = eventAggregator;
        _regionManager = 区域管理器;
    
        // 从数据服务获取数据模型。
        _model = dataService.GetModel();
    
        // 初始化底层模型的 CollectionView。
        DataItemsCV = new ListCollectionView(_model);
        // 跟踪当前选择。
        DataItemsCV.CurrentChanged += new EventHandler(SelectedItemChanged);
    
        // 初始化命令。
        NavigateToViewCommand = new DelegateCommand(NavigateToView);
        SyncViewCommand = new DelegateCommand(SyncView);
    
        LoadModule2Command = new DelegateCommand(LoadModule2);
        _moduleCatalog = 模块目录;
        _moduleManager = 模块管理器;
    }
    
    无效LoadModule2(字符串s)
    {      
        ModuleInfo 模块 = new ModuleInfo()
                            { 
                                Ref =“Module2.dll”,ModuleName =“Module2”, 
                                ModuleType =“Module2.ModuleInit,Module2,版本= 1.0.0.0”, 
                                初始化模式 = 初始化模式.WhenAvailable , 
                             };
        module.DependsOn.Add("模块1");
    
        _moduleCatalog.AddModule(模块);
        _moduleManager.LoadModule("模块2");
    
    }
    

该技术可用于在初始 Shell 初始化后加载模块。我必须承认杰夫的回答有点无关紧要。

I am new to Prism and I have had a similar issue. After much searching, I could not find any direct help. However, I have solved the issue in a different way. Here is the code below:

  1. Created a DelegateCommand Property in the viewmodel class (MasterViewModel) and on the event handler code adds and loads a new module in the Modulecatalog.

  2. Hooked it on to a button's click event on the View's 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. Used the dependency injection to get the references of ModuleCatalog & ModuleManager

  4. On the click event code I added a Module in code(i.e. Module2) to the ModuleCatalog and used Module manager to load it.

    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");
    
    }
    

This technique can be used to load modules after the initial Shell initialisation. I must confess that Geoff's answer was slightly irrelevant.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文