69

Prism for WPF初探(构建简单的模块化开发框架) - 总要有点追求吧

 6 years ago
source link: http://www.cnblogs.com/lelehellow/p/8036655.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Prism for WPF初探(构建简单的模块化开发框架)

  先简单的介绍一下Prism框架,引用微软官方的解释:

Prism provides guidance to help you more easily design and build, flexible, and easy-to-maintain client business apps that run on Windows Runtime, Windows Presentation Foundation (WPF) desktop, Silverlight, or Windows Phone 7. These apps may start small and evolve over time.

官方链接https://msdn.microsoft.com/en-us/library/ff648465.aspx,可下载到文档和示例代码。

  多的介绍就不必了,研究这套框架的人基本是做WPF或者Silverlight的人,我是新人,理解不深还请大神指教。听说Prism是开源的,做了才一年的小菜目前框架都用的不熟,以后再看源码吧。

Prism要用到IOC容器,提供选择的有Unity和MEF,这个系列的博文以后我都选用MEF。不懂MEF的建议看看这位大牛的系列博文http://www.cnblogs.com/yunfeifei/p/3922668.html

先说一下思路:

  1、Prism思想是模块化编程,我将主界面拆分为四个模块(A、B、C、D)。

  2、模块之间不能互相引用,也就是解耦了。

  3、目前就以上两点,要考虑到以后对项目进行扩展,所以预留一个Infrastructure(Project)放置模块之间抽象的东西。

  完成之后的界面图如下:

890372-20171215090948451-363092362.png

  解决方案总体结构:

890372-20171215091121092-1764838856.png

一、基本结构搭建

  1、按照上图结构添加项目,注意只有Desktop.MainWindow中保留App.xaml,并且输出类型是Windows应用程序,其余的Project都要删除App.xaml,输出类型为类库。

  2、删除Desktop.MainWindow中的默认的MainWindow,新建一个Shell窗体,根据Prism的思想,这个Shell就是主窗体。

  3、为所有的Project添加Prism的引用,我这里为所有的Project安装了以下四个Prism的Nuget包。

890372-20171215092815701-142334352.png

  4、在ModuleA中新建类ModuleA,ModuleB,ModuleC,ModuleD,继承自IModule接口,只有继承这个接口才能被加载进Prism中。

using Prism.Modularity;
using Prism.Mef.Modularity;
using Prism.Regions;
using System.ComponentModel.Composition;

namespace ModuleA
{
    [ModuleExport("ModuleA", typeof(ModuleA), InitializationMode = InitializationMode.WhenAvailable)]
    public class ModuleA : IModule
    {  
        private readonly IRegionViewRegistry regionViewRegistry;
        [ImportingConstructor]
        public ModuleA(IRegionViewRegistry registry)
        {
            this.regionViewRegistry = registry;
        }
        public void Initialize()
        {
            regionViewRegistry.RegisterViewWithRegion("RegionA",typeof(View.GridA));
        }
    }
}

注意最后一行代码:

regionViewRegistry.RegisterViewWithRegion("RegionA",typeof(View.GridA));
RegionA就是主界面吧Shell中为ModuleA模块预留的位置,可以理解为占位符,View.GridA就是我们为ModuleA写的的界面。BCD模块同理。

  5、添加一个BootStrapper类,这个类要继承自MefBootstrapper。

  Prism提供四种配置模块加载的方式,看官方文档(这里我提供第一种和第二种方式):

  

890372-20171215093159279-1323097314.png
using Prism.Mef;
using Prism.Modularity;
using Prism;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using ModuleA;

namespace Desktop.MainWindow
{
    public class BootStrapper:MefBootstrapper
    {
        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();
        }

        protected override void ConfigureAggregateCatalog()
        {
            base.ConfigureAggregateCatalog();
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(BootStrapper).Assembly));
            //this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(this.GetType().Assembly));
            //第一种加载方式
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleA.ModuleA).Assembly));
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleB.ModuleB).Assembly));
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleC.ModuleC).Assembly));
            this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ModuleD.ModuleD).Assembly));
        }

        protected override IModuleCatalog CreateModuleCatalog()
        {
            // When using MEF, the existing Prism ModuleCatalog is still the place to configure modules via configuration files.
            return new ConfigurationModuleCatalog();
        }
        //Prism提供四种加载模块的方式,以下是第二种从xaml文件中加载,注意文件要生成Resource,并且始终复制到输出目录
        //protected override IModuleCatalog CreateModuleCatalog()
        //{
        //    this.ModuleCatalog = new ModuleCatalog();
        //    var xamlCatalog = Prism.Modularity.ModuleCatalog.CreateFromXaml(new Uri("ModuleCatalogs.xaml", UriKind.Relative));
        //    //var xamlCatalog = Prism.Modularity.ModuleCatalog.CreateFromXaml(new Uri("ModuleCatalogs.xaml", UriKind.Relative));
        //    foreach (var item in xamlCatalog.Modules)
        //    {
        //        ModuleCatalog.AddModule(item);
        //    }
        //    return xamlCatalog;

        //}
    }
}

  6、在App.xaml中把启动项设置为BootStrapper应该都会吧,不会的看源码哦。至此,一个简单的基于MEF的Prism框架就搭建好了。链接提供源码。

  源码在这呢


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK