zoukankan      html  css  js  c++  java
  • 从PRISM开始学WPF(四)Prism-Module-更新至Prism7.1

    0x4Modules

    Modules是能够独立开发、测试、部署的功能单元,Modules可以被设计成实现特定业务逻辑的模块(如Profile Management),也可以被设计成实现通用基础设施或服务的模块(如Logging、Exception Management)。

    既然Modules能够独立开发、测试、部署,那么如何告诉Shell(我们的宿主程序)去Load哪些Module,以怎样的形式Load这些Module呢?Prism为此提供了一个叫ModuleCatalog的东西。他用这个来管理Module。所以在App启动之初,需要创建配置一个ModuleCatalog。

    [7.1updated]Prism.Modularity在7.1中也改了很多,主要是为了统一api吧,我们就看对wpf的影响:

    1. 在IModule 接口中移除了Initialize()
    2. 新增了两个方法
            //
            // Summary:
            //     Notifies the module that it has be initialized.
            void OnInitialized(IContainerProvider containerProvider);
            //
            // Summary:
            //     Used to register types with the container that will be used by your application.
            void RegisterTypes(IContainerRegistry containerRegistry);
    

    如果升级7.1的话,需要修改所有 IModule 的实现,移除Initialize(),并且实现新接口,这样一来,你将不再从 构造函数中获取module的依赖,而是直接从IContainerProvider获取,接下来的代码,我将更新到7.1,并且尽量说明其中的变动。
    ✏:
    先新增一个WpfApp项目,命名ModuleA,删除App.config和App.xaml,然后将outputType改为Class Library。

    在Views文件夹下面新建一个用户控件ViewA

    新增一个类ModuleAModule.cs实现IModule接口(每一个Module类都要实现这个接口,而每一个Module都要有这样一个类来对Module里的资源统一管理)

    using ModuleA.Views;
    using Prism.Ioc;
    using Prism.Modularity;
    using Prism.Regions;
    
    namespace ModuleA
    {
        public class ModuleAModule : IModule
        {
            public void OnInitialized(IContainerProvider containerProvider)
            {
                var regionManager = containerProvider.Resolve<IRegionManager>();
                regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));
            }
    
            public void RegisterTypes(IContainerRegistry containerRegistry)
            {
                
            }
        }
    }
    

    OnInitialized实现的时候,顺便将一个viewA与ContentRegion进行关联,看代码

                var regionManager = containerProvider.Resolve<IRegionManager>();
                regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));
    

    [7.1updated]记得之前是怎么写的吗?regionManager 是通过构造函数注入的,现在,不需要了,而是直接从containerProvider中解析。

    那么,ModuleCatalog是怎样让Shell加载ModuleA的呢?,,ԾㅂԾ,,

    代码

    先在shell所在module添加ModuleA引用,然后:

    [7.1updated]App.xaml.cs中重写ConfigureModuleCatalog
    
    ```c#
            protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
            {
                moduleCatalog.AddModule<ModuleA.ModuleAModule>();
            }
    ```
    啊妹子,炒鸡简单有没有?
    
    #### 配置文件
    
    ~~~`Bootstrapper.cs`中重写`CreateModuleCatalog`:~~~
    
    [7.1updated]App.xaml.cs中重写CreateModuleCatalog
    ```C#
            protected override IModuleCatalog CreateModuleCatalog()
            {
                return new ConfigurationModuleCatalog();
            }
    ```
    
    这表示,ModuleCatalog将从配置文件中创建。
    
    App.config中添加了<modules>节点,并且指定了需要Load的module,并且设置了startupLoaded参数来告诉shell,是否在启动时就加载他。下面是App.config的内容,他加载了一个名为ModuleAModule的Module,存在ModuleA.dll。
    
    ```xml-dtd
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <configSections>
        <section name="modules" type="Prism.Modularity.ModulesConfigurationSection, Prism.Wpf" />
      </configSections>
      <startup>
      </startup>
      <modules>
        <module assemblyFile="ModuleA.dll" moduleType="ModuleA.ModuleAModule, ModuleA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" moduleName="ModuleAModule" startupLoaded="True" />
      </modules>
    </configuration>
    ```
    
    *通过配置文件来配置ModuleCatalog就不需要添加ModuleA引用了*
    
    
    
    
    
    #### ~~Directory~~
    
    重写IModuleCatalog 方法:
    [7.1Updated] ModulePath 就是你需要加载的module的dll生成目录
    
    ```
            protected override IModuleCatalog CreateModuleCatalog()
            {
                return new DirectoryModuleCatalog() { ModulePath = @".Modules" };
            }
    ```
    #### LoadManual
    
    重写ConfigureModuleCatalog方法:
    
    ```
            protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
            {
                var moduleAType = typeof(ModuleAModule);
                moduleCatalog.AddModule(new ModuleInfo()
                {
                    ModuleName = moduleAType.Name,
                    ModuleType = moduleAType.AssemblyQualifiedName,
                    InitializationMode = InitializationMode.OnDemand
                });
            }
    ```
    
    上面的只是几种加载 module的方式,不做深入的研究了,反正能用就行了,蛮喜欢用 config的模式的
    [7.1updated]从代码片段上看,这里最大的变动就是IModule了,还有就是ConfigureModuleCatalog的时候用到了IModuleCatalog (容器管理?)
  • 相关阅读:
    一致性哈希算法
    Discourse 的标签(Tag)只能是小写的原因
    JIRA 链接 bitbucket 提示错误 Invalid OAuth credentials
    JIRA 如何连接到云平台的 bitbucket
    Apache Druid 能够支持即席查询
    如何在 Discourse 中配置使用 GitHub 登录和创建用户
    Apache Druid 是什么
    Xshell 如何导入 PuTTYgen 生成的 key
    windows下配置Nginx支持php
    laravel连接数据库提示mysql_connect() :Connection refused...
  • 原文地址:https://www.cnblogs.com/hicolin/p/8694892.html
Copyright © 2011-2022 走看看