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 (容器管理?)
  • 相关阅读:
    数往知来C#面向对象准备〈二〉
    数往知来C#之面向对象准备〈一〉
    如果我比别人走得更远些,那是因为我站在巨人的肩上。
    小记一下
    关于servlet
    使用session防止表单重复提交
    session和cookie的区别
    数据结构排序算法Java实现
    用背景渐变的透明度设置不同颜色的背景渐变
    Java用DOM方法解析xml
  • 原文地址:https://www.cnblogs.com/hicolin/p/8694892.html
Copyright © 2011-2022 走看看