首先在介绍本节内容之前,首先来看看官方文档来如何描述Prism 应用的初始化吧!A Prism application requires registration and configuration during the application startup process—this is known as bootstrapping the application,也就是说在在一个Prism应用程序开始之前首先要做的就是注册和配注应用程序,我们以此为突破点,一步步来剖析。

1 What is a Bootstrapper?

Bootstrapper 是一个通过Prism Library来初始化一个应用程序的,我们来看看一个Bootstrapping process的基本步骤:

  2  什么是依赖注入?

  使用 Prism Library创建的应用程序依赖于容器提供的依赖注入, Prism Library提供了两种依赖注入容器:即Unity和MEF(Managed Extensibility Framework),在Prism应用程序中,Bootstrapper的一个重要的职责是创建shell(MainWindow),这是因为Shell依赖于各种服务,比如Region Manager服务,而这些服务恰恰是在Shell在创建之前需要被创建的。

如果你确认是创建MEF或者是Unity容器作为依赖注入容器,那么正确的方法是创建一个类继承自这些容器,然后重写这些基类的虚方法和抽象方法,其中最重要的几个方法是:CreateShell()、InitializeShell()、CreateModuleCatalog(),现在来分别来介绍下这些方法。

  CreateShell():Creates the shell or main window of the application.具体的写法如下面的代码所示:

 protected override DependencyObject CreateShell()
{
return this.Container.Resolve<Shell>();
//return ServiceLocator.Current.GetInstance<Shell>();
}

     仔细看,里面写了两个方法,都是可以的,这里的Shell是一个Window,是主程序,Container是定义在基类UnityBootstrapper中的一个方法,我们通过代码发现通过ServiceLocator.Current.GetInstance<Shell>(); 也能够达到同样的效果,那我们来看一看ServiceLocator到底是什么,实际上ServiceLocator在执行的时候也是通过调用 Container的。

  InitializeShell():在你创建了一个Shell之后,你需要通过InitializeShell()方法来确保Shell的呈现。下面以WPF程序为例来解释下面的代码。

protected override void InitializeShell()
{
   Application.Current.MainWindow = Shell;
   Application.Current.MainWindow.Show();
}

  CreateModuleCatalog():该方法用来创建一个IModuleCatalog,IModuleCatalog的实例用来记录当前哪些模块对于应用程序是可用的,哪些模块是需要下载的,以及当前模块的归属。

下面以一个具体的类来描述如何创建IModuleCatalog的实例。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Prism.Modularity;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Diagnostics;
using System.IO; namespace X.Core.Infrastructure
{
public class AggregateModuleCatalog : IModuleCatalog
{
private List<IModuleCatalog> catalogs = new List<IModuleCatalog>(); public AggregateModuleCatalog()
{
this.catalogs.Add(new ModuleCatalog());
} public ReadOnlyCollection<IModuleCatalog> Catalogs
{
get
{
return this.catalogs.AsReadOnly();
}
} public void AddCatalog(IModuleCatalog catalog)
{
if (catalog == null)
{
throw new ArgumentNullException("catalog");
}
this.catalogs.Add(catalog);
} public IEnumerable<ModuleInfo> Modules
{
get
{
return this.Catalogs.SelectMany(x => x.Modules);
}
} public IEnumerable<ModuleInfo> GetDependentModules(ModuleInfo moduleInfo)
{
var catalog = this.catalogs.Single(x => x.Modules.Contains(moduleInfo));
return catalog.GetDependentModules(moduleInfo);
} public IEnumerable<ModuleInfo> CompleteListWithDependencies(IEnumerable<ModuleInfo> modules)
{
var modulesGroupedByCatalog = modules.GroupBy<ModuleInfo, IModuleCatalog>(module => this.catalogs.Single(catalog => catalog.Modules.Contains(module)));
return modulesGroupedByCatalog.SelectMany(x => x.Key.CompleteListWithDependencies(x));
} public void Initialize()
{
foreach (var catalog in this.Catalogs)
{
catalog.Initialize();
}
} public void AddModule(ModuleInfo moduleInfo)
{
this.catalogs[0].AddModule(moduleInfo);
} }
}

  最后一个需要进行重载的就是ConfigureModuleCatalog()这个方法,这个方法主要是用来配置IModuleCatalog的。

这里也贴出一段代码来看看怎么重载上述的方法。  

protected override void ConfigureModuleCatalog()
{
var catalog = ((X.Core.Infrastructure.AggregateModuleCatalog)ModuleCatalog); if (!System.IO.Directory.Exists(@".\Apps"))
{
System.IO.Directory.CreateDirectory(@".\Apps");
}
if (!System.IO.Directory.Exists(@".\Modules"))
{
System.IO.Directory.CreateDirectory(@".\Modules");
} foreach (string dic in System.IO.Directory.GetDirectories(@".\Apps"))
{
DirectoryModuleCatalog catApp = new DirectoryModuleCatalog() { ModulePath = dic };
catalog.AddCatalog(catApp);
}
foreach (string dic in System.IO.Directory.GetDirectories(@".\Modules"))
{
DirectoryModuleCatalog catApp = new DirectoryModuleCatalog() { ModulePath = dic };
catalog.AddCatalog(catApp);
} ConfigurationModuleCatalog configCatalog = new ConfigurationModuleCatalog();
catalog.AddCatalog(configCatalog);
}

  需要特别注意的是这里我们使用的是DirectoryModuleCatalog,来加载某一个路径下面的DLL,这些都是需要特别说明的,我们首先来看看对于DirectoryModuleCatalog的官方解释:Represets a catalog created from a directory on disk.代表的是一个从磁盘上创建的一个目录,DirectoryModuleCatalog将会扫描当前目录下的内容,定位那些继承自IModule的类,并且将他们添加到目录中去,通过反射的方式,当前程序集会加载到一个新的应用程序域中,当当前程序集被销毁的时候,当前应用程序域将会被摧毁。

下面再介绍另外一段简单的加载应用程序域的方法,此方法不再是加载某一个路径下的应用程序。

protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();
ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
moduleCatalog.AddModule(typeof(HelloWorldModule.MyHelloWorldModule)); }

  这里直接加载MyHelloWorldModule,这个程序模块继承自IModule,下面贴出当前类的代码。

using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions; namespace HelloWorldModule
{
public class MyHelloWorldModule : IModule
{
private readonly IRegionViewRegistry regionViewRegistry; public MyHelloWorldModule(IRegionViewRegistry registry)
{
this.regionViewRegistry = registry;
} public void Initialize()
{
regionViewRegistry.RegisterViewWithRegion("MainRegion", typeof(Views.HelloWorldView));
}
}
}

  这里有一个特别重要的内容,就是通过RegisterViewWithRegion这个函数将当前模块注入到MainRegion中去,那么这个MainRegion到底是哪个区域呢?

我们再来看看Shell的前台中有些什么?

<Window x:Class="HelloWorld.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.codeplex.com/prism"
Title="Hello World" Height="300" Width="300">
<ItemsControl Name="MainRegion" cal:RegionManager.RegionName="MainRegion" />
</Window>

  看到了吗?当Prism加载MyHelloWorldModule这个模块的时候,会匹配RegionManager.RegionName中的 MainRegion,并且将当前模块加载到ItemsControl 中去,关于这一点,在后续的系类中,我都会重点去介绍,下一节我将会重点介绍Prism中的一些重点服务以及创建和配置UnityBootstrapper中的容器......

												

Prism框架研究(二)的更多相关文章

  1. Prism框架研究(一)

    从今天起开始写一个Prism框架的学习博客,今天是第一篇,所以从最基本的一些概念开始学习这个基于MVVM的框架的学习,首先看一下Prism代表什么,这里引用一下比较官方的英文解释来看一下:Prism ...

  2. Prism框架研究(三)

    这一篇主要用来介绍一下基于Prism Library中的核心服务以及如何配置Container,还有一个重要的部分是如何管理各个组件之间的依赖性,下面就这些内容来做一一的介绍. 1 Prism中的核心 ...

  3. 【原创】NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示

    前言 NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能.这其中最流行的无非就是MINA和Netty了,MINA目前的主要版本是MINA2.而Netty的主要版本是Netty3和Netty ...

  4. 在Prism 框架中,实现主程序与模块间 UI 的通信

    背景: 在模块的UI中包含 TreeView 控件,在该树形控件的每一节点前面定义了一个复选框,如图 需求: 在两个不同的应用程序中使用该控件,而它在不同应用程序中的外观则并不一致,按照本例,即一个显 ...

  5. ASP.NET Web API 框架研究 ASP.NET Web API 路由

    ASP.NET Web API 核心框架是一个独立的.抽象的消息处理管道,ASP.NET Web API有自己独立的路由系统,是消息处理管道的组成部分,其与ASP.NET路由系统有类似的设计,都能找到 ...

  6. Prism框架的Module(模块化)编程

    Prism框架用的是新版本的,Prism7.1.关于其中的变动,感兴趣的参考https://www.cnblogs.com/hicolin/p/8694892.html 如何告诉Shell(我们的宿主 ...

  7. 【.NET6+WPF】WPF使用prism框架+Unity IOC容器实现MVVM双向绑定和依赖注入

    前言:在C/S架构上,WPF无疑已经是"桌面一霸"了.在.NET生态环境中,很多小伙伴还在使用Winform开发C/S架构的桌面应用.但是WPF也有很多年的历史了,并且基于MVVM ...

  8. MVC系列——MVC源码学习:打造自己的MVC框架(二:附源码)

    前言:上篇介绍了下 MVC5 的核心原理,整篇文章比较偏理论,所以相对比较枯燥.今天就来根据上篇的理论一步一步进行实践,通过自己写的一个简易MVC框架逐步理解,相信通过这一篇的实践,你会对MVC有一个 ...

  9. JavaScript 框架设计(二)

    JavaScript 高级框架设计 (二) 上一篇,JavaScript高级框架设计(一)我们 实现了对tag标签的选择 下来我们实现对id的选择,即id选择器. 我们将上一篇的get命名为getTa ...

随机推荐

  1. 机器学习算法总结(四)——GBDT与XGBOOST

    Boosting方法实际上是采用加法模型与前向分布算法.在上一篇提到的Adaboost算法也可以用加法模型和前向分布算法来表示.以决策树为基学习器的提升方法称为提升树(Boosting Tree).对 ...

  2. CROI R1

    $CROI$ $R1$ 今天参加了一场比赛,什么比赛呢?CROI. CROI是什么呢? $Challestend$ $Rehtorbegnaro$ $OI$.总的来说就是我们机房的一些神仙出的题啦. ...

  3. maven 标签classifier 研究一下

    研究一下maven的标签: <dependency> <groupId>io.netty</groupId> <artifactId>netty-tcn ...

  4. scrapy 爬取糗事百科

    安装scrapy conda install scrapy 创建scrapy项目 scrapy startproject qiubai 启动pycharm,发现新增加了qiubai这个目录 在spid ...

  5. 使用 OpenSSL 创建私有 CA:1 根证书

    OpenSSL 创建私有 CA 三部曲:使用 OpenSSL 创建私有 CA:1 根证书使用 OpenSSL 创建私有 CA:2 中间证书使用 OpenSSL 创建私有 CA:3 用户证书 OpenS ...

  6. CSS3下的渐变文字效果实现

    如下,第一种方法已实践 一.方法一:借助mask-image属性 可以狠狠地点击这里:CSS3下的渐变文字效果方法一demo 如果您手头上的浏览器是Chrome或是Safari,则您可以在demo页面 ...

  7. H5 34-背景图片

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Python Revisited Day 04 (控制结构与函数)

    目录 4.1 控制结构 4.1.1 条件分支 4.1.2 循环 4.2 异常处理 4.2.1 捕获与产生异常 4.2.2 自定义异常 4.3 自定义函数 Tips 参数默认值为可变时 危险 4.3.1 ...

  9. Python中IO概述

    Python中的io模块是用来处理各种类型的I/O操作流.主要有三种类型的I/O类型:文本I/O(Text I/O),二进制I/O(Binary I/O)和原始I/O(Raw I/O).它们都是通用类 ...

  10. 黑客帝国效果赏析(包含ES6的语法)

    首先,看看效果吧. 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset ...