2. 初始化应用程序

1.概述

Prism使用BootStrapper初始化应用程序,初始化步骤如下:

说明,将LogggerFacade的日志级别设置为Debug可以在日志里看到Prism的启动流程

2.创建日志系统

日志系统是任何一个企业级应用必备的组件,Prism框架本身也依赖于该日志系统,将日志级别设置为Debug可以在日志里看到Prism的启动流程,所以Prism将其放在初始步骤。日志系统本身比较复杂,Prism使用Facade设计模式封装日志系统(准确来说是使用Adapter设计模式),提供接口ILoggerFacade。默认情况下Prism实现一个日志机制TextLogger,该机制将日志信息打印在命令行。你也可以通过实现接口ILoggerFacade实现自己的日志机制。引导程序的方法Run将注册该服务,为了实现自定义的日志服务,你不能直接将服务注册至容器,而必须重写引导程序的方法CreateLogger

3. 创建和配置模块目录

3.1 创建模块目录

模块目录用于跟踪应用程序中模块信息,如哪些已经导入,哪些没有导入,是否需要从远程下载等等。使用方法CreateModuleCatalog创建模块目录,其次引导程序类使用属性ModuleCatalog保存模块目录。你可以实现自己的模块目录,方法是实现接口IModuleCatalog。同创建LoggerFacade,你不能直接注册至容器,而必须重写引导程序的方法CreateModuleCatalog。

protected override IModuleCatalog CreateModuleCatalog()
{
    return new ConfigurationModuleCatalog()
}
3.2 配置模块目录

配置模块目录作用是导入模块信息并存储,使用AddModule方法导入。每个模块信息包含如下内容:

  • DependsOn,依赖模块名称
  • InitializationMode,初始化方式
  • ModuleName,模块名称
  • ModuleType,模块所在程序集名称
  • Ref,程序集在当前机器路径
  • State,模块状态,包括正在导入,没有导入,已经初始化等。

模块不一定在程序启动时导入,可在程序运行时导入。导入方式有很多种,可直接使用方法AddModule导入,可放在配置文件中导入,也可以将模块放在某个目录下,指定Prism从该目录导入。不同导入方式对应不同类型模块目录。你可以重写Prism模块目录实现多级目录。

4. 创建和配置依赖注入容器

4.1 创建容器

Prism以及应用均严重依赖于依赖注入容器,所以有必要在开始创建依赖注入容器,Prism创建容器很简单,使用方法CreateContainer,返回一个新创建的容器。一般该方法不需要我们重写,每个提供依赖注入的容器均提供一个扩展,如Unity提供UnityExtensions。

4.2 配置容器

配置容器最主要的任务是注册核心服务(Prism框架提供)以及应用服务。

4.2.1 注册核心服务

核心服务为了保证Prism框架正常运行,与具体应用程序无关,接口包括:

  • IModuleManager,获取和初始化应用模块
  • IModuleCatalog,包含应用的元数据
  • IModuleInitializer, 初始化模块
  • IRegionManager,注册和管理域
  • IEventAggregator,事件集合
  • ILoggerFacade, 日志服务
  • IServiceLocator, 允许Prism获取容器

核心服务只能被注册一次,并且一般注册为单例。

protected virtual void ConfigureContainer()
{
...
    if (useDefaultConfiguration)
    {
        RegisterTypeIfMissing(typeof(IServiceLocator),
        typeof(UnityServiceLocatorAdapter), true);
        RegisterTypeIfMissing(typeof(IModuleInitializer), typeof(ModuleInitializer),
        true);
...        
    }
}
4.2.2 注册应用服务

应用服务种类繁杂,依据不同业务产生不同服务,注册应用服务也是在配置容器阶段,方法是重写容器扩展的方法ConfigureContainer,先注册核心服务后注册应用服务,如下:

protected override void ConfigureContainer()
{
    base.ConfigureContainer();
    this.RegisterTypeIfMissing(typeof(IModuleTracker), typeof(ModuleTracker), true);
    this.Container.RegisterInstance<CallbackLogger>(this.callbackLogger);
}

应用服务也可以在接口IModule的方法Initialize中注册,

public class DbAccessModule : IModule
{
    public IUnityContainer _container;
    public Config _config;

    public DbAccessModule(IUnityContainer container)
    {
        _container = container;
        _config = _container.Resolve<Config>();
    }
    public void Initialize()
    {
        HisAccess.Connstr = _config.GetHisConnStr();
        IHisAccess hisDb = new HisAccess(_container.Resolve<ILoggerFacade>());
        _container.RegisterInstance(hisDb);
    }
}

HisAccess访问服务在模块DbAccessModule中注册。

配置默认域适配器映射

依据域概念,域是定义在Shell中的逻辑占位符,将模块中的view转换成可放置在Shell中的view,类似一个电源适配器。Prism提供不同域适配器,不同域适配器使用不同控件实现,如适配器ContentControlRegionAdapter使用控件ContentControl实现。在该步骤就是建立域适配器与控件的映射关系。

protected virtual RegionAdapterMappings ConfigureRegionAdapterMappings()
{
    RegionAdapterMappings regionAdapterMappings = ServiceLocator.Current.GetInstance<RegionAdapterMappings>();
    if (regionAdapterMappings != null)
    {
        regionAdapterMappings.RegisterMapping(typeof(Selector), ServiceLocator.Current.GetInstance<SelectorRegionAdapter>());
    }
}

配置默认域行为

这个未知,需要后期深入理解。

注册框架异常类型

框架异常是指不属于系统异常的错误。一般有Prism获取不到ServiceLocator和依赖注入容器获取注册类型失败等异常。

创建Shell

使用方法CreateShell创建Shell,该方法使用ServiceLocator获取容器,接着获取Shell实例。

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

使用ServiceLocator获取容器原因是有多种依赖注入容器可供选择,如Unity,Structmap,AutoFacd等等,对于Prism使用ServiceLocator统一标记,这样就不会依赖特定容器。

初始化Shell

初始化Shell很简单,一般是为了设置当前应用主窗口并显示主窗口。

初始化模块

初始化模块是获取模块管理者并运行。

posted @ 2020-11-01 23:11  饮冰少年  阅读(390)  评论(0编辑  收藏  举报