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

简介: 索引 【翻译】WPF应用程序模块化开发快速入门(使用Prism框架)【上】 【翻译】WPF应用程序模块化开发快速入门(使用Prism+MEF)【中】 系统启动 系统使用Bootstrapper类型来启动程序,并初始化主窗口 /// /// Interaction logic for App.

索引

【翻译】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);
        }
 关键类
(略)
这个系列含金量不高啊
目录
相关文章
|
2月前
|
C# 开发者 Windows
WPF 应用程序开发:一分钟入门
本文介绍 Windows Presentation Foundation (WPF),这是一种用于构建高质量、可缩放的 Windows 桌面应用程序的框架,支持 XAML 语言,方便 UI 设计与逻辑分离。文章涵盖 WPF 基础概念、代码示例,并深入探讨常见问题及解决方案,包括数据绑定、控件样式与模板、布局管理等方面,帮助开发者高效掌握 WPF 开发技巧。
159 65
|
30天前
|
设计模式 前端开发 C#
使用 Prism 框架实现导航.NET 6.0 + WPF
使用 Prism 框架实现导航.NET 6.0 + WPF
76 10
|
3月前
|
C# 微服务 Windows
模块化革命:揭秘WPF与微服务架构的完美融合——从单一职责原则到事件聚合器模式,构建高度解耦与可扩展的应用程序
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中借鉴微服务架构思想,实现模块化设计。通过将WPF应用分解为独立的功能模块,并利用事件聚合器实现模块间解耦通信,可以有效提升开发效率和系统可维护性。文中还提供了具体示例代码,展示了如何使用事件聚合器进行模块间通信,以及如何利用依赖注入进一步提高模块解耦程度。此方法不仅有助于简化复杂度,还能使应用更加灵活易扩展。
89 0
|
3月前
|
测试技术 C# 开发者
“代码守护者:详解WPF开发中的单元测试策略与实践——从选择测试框架到编写模拟对象,全方位保障你的应用程序质量”
【8月更文挑战第31天】单元测试是确保软件质量的关键实践,尤其在复杂的WPF应用中更为重要。通过为每个小模块编写独立测试用例,可以验证代码的功能正确性并在早期发现错误。本文将介绍如何在WPF项目中引入单元测试,并通过具体示例演示其实施过程。首先选择合适的测试框架如NUnit或xUnit.net,并利用Moq模拟框架隔离外部依赖。接着,通过一个简单的WPF应用程序示例,展示如何模拟`IUserRepository`接口并验证`MainViewModel`加载用户数据的正确性。这有助于确保代码质量和未来的重构与扩展。
67 0
|
3月前
|
C# 开发者 Windows
震撼发布:全面解析WPF中的打印功能——从基础设置到高级定制,带你一步步实现直接打印文档的完整流程,让你的WPF应用程序瞬间升级,掌握这一技能,轻松应对各种打印需求,彻底告别打印难题!
【8月更文挑战第31天】打印功能在许多WPF应用中不可或缺,尤其在需要生成纸质文档时。WPF提供了强大的打印支持,通过`PrintDialog`等类简化了打印集成。本文将详细介绍如何在WPF应用中实现直接打印文档的功能,并通过具体示例代码展示其实现过程。
273 0
|
3月前
|
开发者 C# 自然语言处理
WPF开发者必读:掌握多语言应用程序开发秘籍,带你玩转WPF国际化支持!
【8月更文挑战第31天】随着全球化的加速,开发多语言应用程序成为趋势。WPF作为一种强大的图形界面技术,提供了优秀的国际化支持,包括资源文件存储、本地化处理及用户界面元素本地化。本文将介绍WPF国际化的实现方法,通过示例代码展示如何创建和绑定资源文件,并设置应用程序语言环境,帮助开发者轻松实现多语言应用开发,满足不同地区用户的需求。
64 0
|
3月前
|
开发者 C# UED
WPF多窗口应用程序开发秘籍:掌握窗口创建、通信与管理技巧,轻松实现高效多窗口协作!
【8月更文挑战第31天】在WPF应用开发中,多窗口设计能显著提升用户体验与工作效率。本文详述了创建新窗口的多种方法,包括直接实例化`Window`类、利用`Application.Current.MainWindow`及自定义方法。针对窗口间通信,介绍了`Messenger`类、`DataContext`共享及`Application`类的应用。此外,还探讨了布局控件与窗口管理技术,如`StackPanel`与`DockPanel`的使用,并提供了示例代码展示如何结合`Messenger`类实现窗口间的消息传递。总结了多窗口应用的设计要点,为开发者提供了实用指南。
205 0
|
3月前
|
C# 前端开发 UED
WPF数据验证实战:内置控件与自定义规则,带你玩转前端数据验证,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据验证是确保输入正确性的关键环节。前端验证能及时发现错误,提升用户体验和程序可靠性。本文对比了几种常用的WPF数据验证方法,并通过示例展示了如何使用内置验证控件(如`TextBox`)及自定义验证规则实现有效验证。内置控件结合`Validation`类可快速实现简单验证;自定义规则则提供了更灵活的复杂逻辑支持。希望本文能帮助开发者更好地进行WPF数据验证。
101 0
|
3月前
|
前端开发 C# 开发者
WPF开发者必读:MVVM模式实战,轻松构建可维护的应用程序,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,MVVM(Model-View-ViewModel)模式通过分离关注点,提高了代码的可维护性和可扩展性。本文详细介绍了MVVM模式的三个核心组件:Model(数据模型)、View(用户界面)和ViewModel(处理数据绑定与逻辑),并通过示例代码展示了如何在WPF项目中实现MVVM模式。通过这种模式,开发者可以更高效地构建桌面应用程序。希望本文能帮助你在WPF开发中更好地应用MVVM模式。
162 0
|
3月前
|
开发者 C# Windows
WPF布局大揭秘:掌握布局技巧,轻松创建响应式用户界面,让你的应用程序更上一层楼!
【8月更文挑战第31天】在现代软件开发中,响应式用户界面至关重要。WPF(Windows Presentation Foundation)作为.NET框架的一部分,提供了丰富的布局控件和机制,便于创建可自动调整的UI。本文介绍WPF布局的基础概念与实现方法,包括`StackPanel`、`DockPanel`、`Grid`等控件的使用,并通过示例代码展示如何构建响应式布局。了解这些技巧有助于开发者优化用户体验,适应不同设备和屏幕尺寸。
70 0