• 【翻译】WPF应用程序模块化开发快速入门(使用Prism+MEF)【下】


    索引

    【翻译】WPF应用程序模块化开发快速入门(使用Prism框架)【上】

    【翻译】WPF应用程序模块化开发快速入门(使用Prism+MEF)【中】

    系统启动

    系统使用Bootstrapper类型来启动程序,并初始化主窗口

        /// <summary>
        /// Interaction logic for App.xaml
        /// </summary>
        public partial class App : Application
        {
            protected override void OnStartup(StartupEventArgs e)
            {
                base.OnStartup(e);
    
                // The boostrapper will create the Shell instance, so the App.xaml does not have a StartupUri.
                QuickStartBootstrapper bootstrapper = new QuickStartBootstrapper();
                bootstrapper.Run();
            }
        }
     

    QuickStartBootstrapper类型继承自MefBootstrapper类型

    为了创建和显示主窗口,此类型重写了CreateShell和InitializeShell方法

            protected override DependencyObject CreateShell()
            {
                return this.Container.GetExportedValue<Shell>();
            }
            protected override void InitializeShell()
            {
                base.InitializeShell();
    
                Application.Current.MainWindow = (Shell) this.Shell;
                Application.Current.MainWindow.Show();
            }
     
     
    创建模块
    在此快速入门示例中
    创建了六个模块
    这些模块都实现了IModule接口
    添加了相关的特性
    选择了依赖属性
        [ModuleExport(typeof(ModuleA), DependsOnModuleNames = new string[] { "ModuleD" })]
        public class ModuleA : IModule
    当使用MEF框架的时候
    ModuleExport特性允许MEF发现适当的、
    继承自IModule接口的类型。
    此外:它还支持详细说明额外模块的元数据
    注册模块
    在快速入门示例中
    系统直接引用了一些模块
    通过监控目录发现了一些模块
    还有一些模块是通过配置文件加载的
    QuickStartBootstrapper类型还重写了
    CreateModuleCatalog和ConfigureModuleCatalog方法
    这样就可以通过配置文件来注册模块
    使用MEF时
    AggregateCatalog支持发现模块和类型
    基于此,
    QuickStartBootstrapper重写ConfigureAggregateCatalog
    模版方法并使用MEF注册程序集
    仍然使用ModuleCatalog加载配置文件来注册模块
            protected override IModuleCatalog CreateModuleCatalog()
            {
                // When using MEF, the existing Prism ModuleCatalog is still the place to configure modules via configuration files.
                return new ConfigurationModuleCatalog();
            }
            protected override void ConfigureAggregateCatalog()
            {
                base.ConfigureAggregateCatalog();
    
                // Add this assembly to export ModuleTracker
                this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(QuickStartBootstrapper).Assembly));
    
                // Module A is referenced in in the project and directly in code.
                this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleA).Assembly));
                this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleC).Assembly));
    
                // Module B and Module D are copied to a directory as part of a post-build step.
                // These modules are not referenced in the project and are discovered by inspecting a directory.
                // Both projects have a post-build step to copy themselves into that directory.
                DirectoryCatalog catalog = new DirectoryCatalog("DirectoryModules");
                this.AggregateCatalog.Catalogs.Add(catalog);
            }

    加载模块

     在此快速入门中
    即有在系统启动时加载模块的业务
    也有按需加载模块的业务
    还有显示进度、控制模块间的依赖性等业务
    注意:
    此快速入门示例还有一些额外的类
    以帮助追踪模块初始化的状态信息
    这些类主要是起了示范的目的
    Shell的用户界面里包含了六个ModuleControl
    Shell的DataContext是ModuleTracker
    ModuleTracker类型为每个模块保存一个ModuleTrackingState
    ModuleTrackingState绑定到与之对应的ModuleControl
    ModuleControl使用一个默认的样式来展现模块的加载和初始化状态
    当点击ModuleControl自定义控件的时候
    将触发如下事件:
            /// <summary>
            /// Handles the RequestModuleLoad event of the ModuleC control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
            private void ModuleC_RequestModuleLoad(object sender, EventArgs e)
            {
                // The ModuleManager uses the Async Events Pattern.
                this.moduleManager.LoadModule(WellKnownModuleNames.ModuleC);
            }
     
    此事件被触发的时候会同时触发moduleManager的ModuleDownloadProgressChanged事件
    此事件是在shell页面的OnImportsSatisfied方法中被注册的
                this.moduleManager.LoadModuleCompleted += this.ModuleManager_LoadModuleCompleted;
                this.moduleManager.ModuleDownloadProgressChanged += this.ModuleManager_ModuleDownloadProgressChanged;
     
            /// <summary>
            /// Handles the LoadModuleProgressChanged event of the ModuleManager control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="Microsoft.Practices.Composite.Modularity.ModuleDownloadProgressChangedEventArgs"/> instance containing the event data.</param>
            private void ModuleManager_ModuleDownloadProgressChanged(object sender, ModuleDownloadProgressChangedEventArgs e)
            {
                this.moduleTracker.RecordModuleDownloading(e.ModuleInfo.ModuleName, e.BytesReceived, e.TotalBytesToReceive);
            }

    当模块加载完成后

    shell页面也会被通知到

            /// <summary>
            /// Handles the LoadModuleCompleted event of the ModuleManager control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="Microsoft.Practices.Composite.Modularity.LoadModuleCompletedEventArgs"/> instance containing the event data.</param>
            private void ModuleManager_LoadModuleCompleted(object sender, LoadModuleCompletedEventArgs e)
            {
                this.moduleTracker.RecordModuleLoaded(e.ModuleInfo.ModuleName);
            }
     关键类
    (略)
    这个系列含金量不高啊
  • 相关阅读:
    Arch 真好用
    Spring 自定义注解-字段注解
    Raft论文概述
    Raft成员变化(Membership Change)
    Reactor模式详解
    高性能IO之Reactor模式
    WinFrm中多线程操作窗体属性
    Reactor模式
    高并发中的线程与线程池
    二层交换机与三层交换机区别详解!
  • 原文地址:https://www.cnblogs.com/liulun/p/2417419.html
Copyright © 2020-2023  润新知