【ABP框架系列学习】模块系统(4)
原文:【ABP框架系列学习】模块系统(4)

0.引言

ABP提供了构建模块和通过组合模块以创建应用程序的基础设施。一个模块可以依赖于另外一个模块。通常,程序集可以认为是模块。如果创建多个程序集的应用程序,建议为每个程序集创建模块定义。

当前,模块系统主要集中在服务器,而不是客户端。

1.模块定义

模块是从ABP包中的AbpModule派生的类定义的。比如说开发一个可以用于不同应用程序的博客模块(Blog Module)。最简单的模块定义如下 :

public class MyBlogApplicationModule : AbpModule
{public override void Initialize(){IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());}
}

模块定义类负责通过依赖注入注册类,如有必要(可以像上述事例按惯例完成)。它还可以配置应用程序和其它模块,给应用程序增加新的功能等等。

2.生命周期方法

ABP在程序启动和关闭时调用模块一些特定的方法。你可以重写这些方法以执行某些特定的任务。

ABP按照依赖顺序调用这些方法。如果模块A依赖模块B,那么模块B在模块A之前初始化。

启动方法执行准确的顺序:PreInitialize-B, PreInitialize-A, Initialize-B, Initialize-A, PostInitialize-B, PostInitialize-A。对于所有依赖关系图都是如此。关闭方法也是类似的,但顺序相反。

相关源码:模块启动时依次执行PreInitialize()、Initialize()、PostInitialize(),模块关闭时首先Reverse()、然后在逐个模块Shutdown()。

        public virtual void StartModules(){var sortedModules = _modules.GetSortedModuleListByDependency();sortedModules.ForEach(module => module.Instance.PreInitialize());sortedModules.ForEach(module => module.Instance.Initialize());sortedModules.ForEach(module => module.Instance.PostInitialize());}public virtual void ShutdownModules(){Logger.Debug("Shutting down has been started");var sortedModules = _modules.GetSortedModuleListByDependency();sortedModules.Reverse();sortedModules.ForEach(sm => sm.Instance.Shutdown());Logger.Debug("Shutting down completed.");}

PreInitialize

当应用程序启动时,首先调用该方法。它是框架和其它模块初始化之前配置它们的首选方法。

你还可以在该方法中编写特定的代码,以便在依赖注入注册之前运行。例如,如果你创建一个传统的注册类,那么你应在该方法中使用IOCManager.AddConventionalRegisterer方法注册它们。

Initialize

该方法是依赖注入注册的地方,通过使用IocManager.RegisterAssemblyByConvention方法完成注册。如果想定义自定义的依赖注册,请见后续依赖注入章节。

PostInitialize

该方法在程序启动的最后调用。在这里解析依赖是安全的。

Shutdown

该方法在程序关闭时调用。

3.模块依赖(Module Dependencies)

一个模块可以依赖于另外的模块。你可以通过DependsOn特性显示声明依赖项,如下代码:

[DependsOn(typeof(MyBlogCoreModule))]
public class MyBlogApplicationModule : AbpModule
{public override void Initialize(){IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());}
}

上述事例代码中,声明了MyBlogApplicationModule模块依赖于MyBlogCoreModule模块,那么MyBlogCoreModule模块应该在MyBlogApplicationModule模块之前完成初始化。

ABP可以从启动模块(start module)开始就递归的解析依赖关系,并相应地初始化它们。启动模块(start module)是最后进行初始化的模块。

4.插件模块

虽然模块从启动模块开始查找并遍历依赖关系,ABP还可以动态加载模块。AbpBootstrapper类中定义了PlugInSources属性,该属性可用于向动态加载的插件模块添加源。插件源可以是实现IPlugInSource接口的任何类。通过实现FolderPlugInSource类以从指定文件夹中的程序集获取插件模块。

ASP.NET CORE

ABP中ASP.NET CORE模块在AddAbp扩展方法中定义选项,用于在启动类中添加插件源:

services.AddAbp<MyStartupModule>(options =>
{options.PlugInSources.Add(new FolderPlugInSource(@"C:\MyPlugIns"));
});

也可以使用更简单的语法AddFolder扩展方法:

services.AddAbp<MyStartupModule>(options =>
{options.PlugInSources.AddFolder(@"C:\MyPlugIns");
});

ASP.NET MVC,Web API

对于传统的ASP.NET MVC应用程序,可以通过重写global.asax文件中Application_Start方法添加插件文件夹,如下代码:

public class MvcApplication : AbpWebApplication<MyStartupModule>
{protected override void Application_Start(object sender, EventArgs e){AbpBootstrapper.PlugInSources.AddFolder(@"C:\MyPlugIns");//...base.Application_Start(sender, e);}
}

Controllers in PlugIns

如果你的模块包括MVC或Web API Controolers,ASP.NET不能查找你的控制器。为了克服这个问题,你可以修改global.asax文件,如下代码:

using System.Web;
using Abp.PlugIns;
using Abp.Web;
using MyDemoApp.Web;[assembly: PreApplicationStartMethod(typeof(PreStarter), "Start")]namespace MyDemoApp.Web
{public class MvcApplication : AbpWebApplication<MyStartupModule>{}public static class PreStarter{public static void Start(){//...MvcApplication.AbpBootstrapper.PlugInSources.AddFolder(@"C:\MyPlugIns\");MvcApplication.AbpBootstrapper.PlugInSources.AddToBuildManager();}}
}

附加程序集(Additional Assemblies)

默认实现IAssemblyFinder和ITypeFinder接口只能在这些程序集中查找模块程序集和类型。也可以在模块中重写GetAdditionalAssembliesy方法来包括其它程序集。

自定义模块方法(Custom Module Methods)

你的模块还可以拥有自定义的方法,并能在依赖于这个模块的其它模块中调用这个方法。假设MyModule2依赖于MyModule1,并想在PreInitialize方法中调用MyModule1模块中的方法。

public class MyModule1 : AbpModule
{public override void Initialize(){IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());}public void MyModuleMethod1(){//this is a custom method of this module
    }
}[DependsOn(typeof(MyModule1))]
public class MyModule2 : AbpModule
{private readonly MyModule1 _myModule1;public MyModule2(MyModule1 myModule1){_myModule1 = myModule1;}public override void PreInitialize(){_myModule1.MyModuleMethod1(); //Call MyModule1's method
    }public override void Initialize(){IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());}
}

在上述代码中,通过构造函数把MyModule1注入到MyModule2,所以MyModule2可以调用MyModule1中的自定义方法,前提是MyModule2依赖于MyModule1。

模块配置(Module Configuration)

然而自定义方法可以用来配置模块,建议使用启动配置(startup configuration)系统来定义和设置模块的配置。

模块生命周期(Module Lifetime)

模块类自动注册为单实例对象(singleton)。

posted on 2018-11-26 08:29 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/10018426.html

【ABP框架系列学习】模块系统(4)相关推荐

  1. 【ABP框架系列学习】模块系统之插件示例开发

    0.引言 上一篇博文主要介绍了ABP模块及插件的相关知识,本章节主要开发一个插件示例来学习如何创建一个插件,并在应用程序中使用.这个命名为FirstABPPlugin的插件主要在指定的时间段内删除审计 ...

  2. 【ABP框架系列学习】N层架构(3)

    目录 0.引言 1.DDD分层 2.ABP应用构架模型 客户端应用程序(Client Applications) 表现层(Presentation Layer) 分布式服务层(Distributed ...

  3. 基于领域驱动设计思想Abp框架的考试系统

    后端使用企业技术,但有部分阉割. 使用技术: 数据库:Sql Server 后端:.Net5.ABP vNext.AutoMapper.AutoFac.Dapper.EPlus 前端:Vue.js + ...

  4. abp框架(aspnetboilerplate)扩展系统表

    以OrganizationUnit为例,进行扩展,加入IsUse属性 1.创建一个新类,比如ExtendedOrganizationUnit,继承OrganizationUnit public cla ...

  5. [Abp vNext 源码分析] - 2. 模块系统的变化

    一.简要说明 本篇文章主要分析 Abp vNext 当中的模块系统,从类型构造层面上来看,Abp vNext 当中不再只是单纯的通过 AbpModuleManager 来管理其他的模块,它现在则是 I ...

  6. ABP官方文档(三)【模块系统】

    1.3 ABP总体介绍 - 模块系统 1.3.1 ABP模块系统简介 ABP框架提供了创建和组装模块的基础,一个模块能够依赖于另一个模块.在通常情况下,一个程序集就可以看成是一个模块.在ABP框架中, ...

  7. ABP框架 v3.0 已发布!

    我们很高兴地宣布,ABP框架和ABP商业版3.0版已经发布.与常规的2周发布一个版本不同的是, 这个版本用了4周的时间.关闭了119个issue,合并了89个pull request 和主框架仓库中的 ...

  8. ABP框架 v2.7.0已经发布!

    ABP框架和ABP商业版 v2.7已经发布.我们没有为2.4,2.5和2.6发布博客文章,所以这篇文章也将涵盖这几个版本中新增内容和过去的2个月里我们完成了什么. 关于发布周期与开发 之前说过我们已经 ...

  9. abp框架mysql连接配置,abp框架连接数据库

    ABP框架搭建项目系列教程基础版完结篇 经过前面十二篇的基础教程,现在终于该做个总结了. 回顾 第一篇,我们建议新手朋友们先通过ABP官网的启动模板生成解决方案,因为这样既快速又准确,不会因为项目的搭 ...

最新文章

  1. golang经典书籍--go并发编程
  2. php 这样写日志 sleep你会了吗?
  3. js动态改变下拉菜单内容示例 .
  4. 数据中心用蓄电池解决方案
  5. php mysql 插入多条数据_雷林鹏分享:PHP MySQL 插入多条数据
  6. android开发,设置listview的高度无效
  7. 9008刷机模式写入超时刷机帮_【转】高通9008模式刷机,让小米刷机不再畏惧
  8. 软件接口与性能测试,接口测试与性能测试有什么区别?
  9. Google Chrome如何恢复误删除书签和文件夹
  10. python网络请求_python发送网络请求
  11. 第22章 声音与音乐
  12. java校园快递代领系统 小程序
  13. 半导体技术科普:解读第三代半导体及宽禁带半导体
  14. Excel中计算个人所得税的公式
  15. HDFS命令:hdfs dfs
  16. 为什么很多毕业生逃不过被大型IT培训机构套路?
  17. 中小企业信息化(一)——何为信息化
  18. [CSP-S模拟测试]:影魔(树状数组+线段树合并)
  19. html5 网络断开,网络连接频繁断开是怎么回事
  20. 学习笔记:人脸检测和人脸识别

热门文章

  1. Android程序等待1,android – Espresso如何等待一段时间(1小时)?
  2. php mysql 日期时间_php Mysql日期和时间函数集合
  3. python修改类的属性值_python 四种方法修改类变量,实例对象调用类方法改变类属性的值,类对象调用类方法改变类属性的值,调用实例方法改变类属性的值,直接修改类属性的值...
  4. c语言printf右移,C语言printf(“”)左右(转)
  5. dedeampz mysql启动不了_localhost打不开?dedeampz环境启动不了?本地php环境启动失败?...
  6. 苹果6s怎么连不上服务器未响应,iphone6s无法连接app store 苹果6s连不上app store解决方法...
  7. python实现rsa加密源代码_python实现RSA加密(解密)算法
  8. 牛逼!Python常用数据类型的基本操作(长文系列第①篇)
  9. 中国大学前10强!校友会2020世界一流大学排名发布
  10. Python爬取京东笔记本电脑,来看看那个牌子最棒