前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【翻译】WPF应用程序模块化开发快速入门(使用Prism+MEF)【下】

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

作者头像
liulun
发布2022-05-09 12:34:50
7520
发布2022-05-09 12:34:50
举报
文章被收录于专栏:liulun

索引

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

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

系统启动

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

代码语言:javascript
复制
    /// <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方法

代码语言:javascript
复制
        protected override DependencyObject CreateShell()
        {
            return this.Container.GetExportedValue<Shell>();
        }
代码语言:javascript
复制
        protected override void InitializeShell()
        {
            base.InitializeShell();

            Application.Current.MainWindow = (Shell) this.Shell;
            Application.Current.MainWindow.Show();
        }
代码语言:javascript
复制
创建模块
代码语言:javascript
复制
在此快速入门示例中
代码语言:javascript
复制
创建了六个模块
代码语言:javascript
复制
这些模块都实现了IModule接口
代码语言:javascript
复制
添加了相关的特性
代码语言:javascript
复制
选择了依赖属性
代码语言:javascript
复制
    [ModuleExport(typeof(ModuleA), DependsOnModuleNames = new string[] { "ModuleD" })]
    public class ModuleA : IModule
代码语言:javascript
复制
当使用MEF框架的时候
代码语言:javascript
复制
ModuleExport特性允许MEF发现适当的、
代码语言:javascript
复制
继承自IModule接口的类型。
代码语言:javascript
复制
此外:它还支持详细说明额外模块的元数据
代码语言:javascript
复制
注册模块
代码语言:javascript
复制
在快速入门示例中
代码语言:javascript
复制
系统直接引用了一些模块
代码语言:javascript
复制
通过监控目录发现了一些模块
代码语言:javascript
复制
还有一些模块是通过配置文件加载的
代码语言:javascript
复制
QuickStartBootstrapper类型还重写了
代码语言:javascript
复制
CreateModuleCatalog和ConfigureModuleCatalog方法
代码语言:javascript
复制
这样就可以通过配置文件来注册模块
代码语言:javascript
复制
使用MEF时
代码语言:javascript
复制
AggregateCatalog支持发现模块和类型
代码语言:javascript
复制
基于此,
代码语言:javascript
复制
QuickStartBootstrapper重写ConfigureAggregateCatalog
代码语言:javascript
复制
模版方法并使用MEF注册程序集
代码语言:javascript
复制
仍然使用ModuleCatalog加载配置文件来注册模块
代码语言:javascript
复制
        protected override IModuleCatalog CreateModuleCatalog()
        {
            // When using MEF, the existing Prism ModuleCatalog is still the place to configure modules via configuration files.
            return new ConfigurationModuleCatalog();
        }
代码语言:javascript
复制
        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);
        }

加载模块

代码语言:javascript
复制
 在此快速入门中
代码语言:javascript
复制
即有在系统启动时加载模块的业务
代码语言:javascript
复制
也有按需加载模块的业务
代码语言:javascript
复制
还有显示进度、控制模块间的依赖性等业务
代码语言:javascript
复制
注意:
代码语言:javascript
复制
此快速入门示例还有一些额外的类
代码语言:javascript
复制
以帮助追踪模块初始化的状态信息
代码语言:javascript
复制
这些类主要是起了示范的目的
代码语言:javascript
复制
Shell的用户界面里包含了六个ModuleControl
代码语言:javascript
复制
Shell的DataContext是ModuleTracker
代码语言:javascript
复制
ModuleTracker类型为每个模块保存一个ModuleTrackingState
代码语言:javascript
复制
ModuleTrackingState绑定到与之对应的ModuleControl
代码语言:javascript
复制
ModuleControl使用一个默认的样式来展现模块的加载和初始化状态
代码语言:javascript
复制
当点击ModuleControl自定义控件的时候
代码语言:javascript
复制
将触发如下事件:
代码语言:javascript
复制
        /// <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);
        }
代码语言:javascript
复制
此事件被触发的时候会同时触发moduleManager的ModuleDownloadProgressChanged事件
代码语言:javascript
复制
此事件是在shell页面的OnImportsSatisfied方法中被注册的
代码语言:javascript
复制
            this.moduleManager.LoadModuleCompleted += this.ModuleManager_LoadModuleCompleted;
            this.moduleManager.ModuleDownloadProgressChanged += this.ModuleManager_ModuleDownloadProgressChanged;
代码语言:javascript
复制
        /// <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页面也会被通知到

代码语言:javascript
复制
        /// <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);
        }
代码语言:javascript
复制
 关键类
代码语言:javascript
复制
(略)
代码语言:javascript
复制
这个系列含金量不高啊
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2012-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档