ABP模块系统

介绍

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

  模块系统是在服务端的不在客户端。

模块定义

  模块使用继承于AbpModule的类定义。比方说我们开发了一个可以用在不同应用的博客模块,最简单的定义方法如下所示:

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

  如果需要的话,模块定义类负责将当前模块注册到依赖注入(如上面代码中所示)。还可以配置应用和其他模块,添加新特征到应用程序等。

生命周期方法

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

  ABP根据依赖顺序调用这些方法。如果模块A依赖于模块B,模块B会在模块A之前初始化。确切的启动方法顺序为:      Preinitialize-B,PreInitialize-B,Initialize-B,Initialize-A,PostInitialize-B,PostInitialize-A。对所有的依赖关系图都是如此。Shutdown方法也相似,但是顺序相反。

PreInitialize

  当应用启动时首先被调用的方法。通常用来配置框架和其他模块,在他们初始化之前。

  也可以在这个方法里写一些特定需要运行的代码在依赖注入注册之前。例如,如果创建了一个常见的注册类,可以在这里使用IocManager.AddConventionalRegisterer方法。

Initialize

  这里通常是依赖注入注册完成的地方。一般使用IocManagerAssemblyByConvention方法。如果想定义定制的依赖注册,参见依赖注入文档。

PostInitialize

  这个方法在启动过程中最后调用。在这里解决依赖是安全的。

Shutdown

  这个方法当应用关闭的时候调用。

模块依赖

  一个模块可以依赖于另一个模块。需要使用DependsOn特性显示声明依赖,如下:

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

  这样我们就告诉ABP,MyBlogApplicationModule 模块依赖于MyBlogCoreModule ,MyBlogCoreModule 模块应该在MyBlogApplicationModule 之前初始化。

  ABP可以从启动模块开始递归解决模块依赖,并且相应的初始化模块。启动模块最后初始化。

插件模块

  当模块从启动模块开始研究并进入依赖关系时,ABP可以动态的加载模块。AbpBootstrapper类定义了PlugInSources属性,这个属性可以用来动态添加插件源到加载插件模块。一个插件源可以是任何实现了IplungInSource接口的类。PlugInFolderSource 类实现了这个接口,可以从一个文件夹中的程序集里获取插件模块。

ASP.NET Core

在启动类中,ABP ASP.NET Core模块在AddAbp扩展方法的options中添加插件源:
services.AddAbp<MyStartupModule>(options =>
{
options.PlugInSources.Add(new FolderPlugInSource(@"C:\MyPlugIns"));
});

  我们可以用简单的语法使用AddFolder扩展方法:

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

  参见ASP.NET Core 文档查看在启动类中的更多信息。

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);
}
}

插件中的控制器

  如果模块中包含MVC或Web API控制器,ABP不能调查控制器。为了解决这个问题,可以按如下所示改变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();
}
}
}

附加程序集

  IAssemblyFinder 和 ITypeFinder(ABP用来调查应用中的特定类) 的默认实现只查找模块程序集和在这些程序集中的类型。我们可以重写我们模块中的GetAdditionalAssemblies 方法把额外的程序集包含进来。

自定义模块方法

  模块中可以有自定义方法,这些方法可以被其他的依赖于本模块的模块调用。假定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的方法了。这种情况只有Module2依赖于Module1的情况下才可以。

模块配置

  虽然自定义模块方法可以配置模块,但我们建议使用启动配置系统定义、设置模块的配置。

模块生命周期

  模块类自动注册为单例的。

返回主目录

ABP官方文档翻译 1.3 模块系统的更多相关文章

  1. ABP官方文档翻译 8.1 通知系统

    通知系统 介绍 发送模型 通知类型 通知数据 通知严重性 关于通知持久化 订阅通知 发布通知 用户通知管理 实时通知 客户端 通知存储 通知定义 介绍 在系统中通知用来基于特定的事件告知用户.ABP提 ...

  2. 0.0 ABP官方文档翻译目录

    一直想学习ABP,但囿于工作比较忙,没有合适的契机,当然最重要的还是自己懒.不知不觉从毕业到参加工作七年了,没留下点儿什么,总感觉很遗憾,所以今天终于卯足劲鼓起勇气开始写博客.有些事能做的很好,但要跟 ...

  3. ABP官方文档翻译 6.3 本地化

    本地化 介绍 应用程序语言 本地化源 XML文件 注册XML本地化源 JSON文件 注册JSON本地化源 资源文件 自定义源 当前语言是如何决定的 ASP.NET Core ASP.NET MVC 5 ...

  4. ABP官方文档翻译 5.3 OData集成

    OData集成 介绍 安装 安装Nuget包 设置模块依赖 配置实体 创建控制器 配置 示例 获取实体列表 Request Response 获取单个实体 Request Response 使用导航属 ...

  5. ABP官方文档翻译 0.0 ABP官方文档翻译目录

    一直想学习ABP,但囿于工作比较忙,没有合适的契机,当然最重要的还是自己懒.不知不觉从毕业到参加工作七年了,没留下点儿什么,总感觉很遗憾,所以今天终于卯足劲鼓起勇气开始写博客.有些事能做的很好,但要跟 ...

  6. ABP官方文档翻译 1.4 启动配置

    启动配置 配置ABP 替换内置服务 配置模块 创建模块配置 ABP提供了基础设施和模型在启动的时候对它及模块进行配置. 配置ABP 在模块的PreInitialize事件中配置ABP.示例配置如下: ...

  7. ABP官方文档翻译 2.1 依赖注入

    依赖注入 什么是依赖注入 传统方式的问题 解决方案 构造函数注入模式 属性注入模式 依赖注入框架 ABP依赖注入基础设施 注册依赖注入 传统注册 帮助接口 自定义/直接注册 使用IocManager ...

  8. ABP官方文档翻译 4.1 应用服务

    应用服务 IApplicationService接口 ApplicationService类 CrudService和AsyncCrudAppService类 简单的CRUD应用服务示例 自定义CRU ...

  9. ABP官方文档翻译 2.5 设置管理

    设置管理 介绍 关于 ISettingStore 定义设置 设置范围 重写设置定义 获取设置值 服务端 客户端 更改设置 关于缓存 介绍 每个应用都需要存储设置,并且在应用的某些地方需要使用这些设置. ...

随机推荐

  1. 内存泄露,GC相关

    内存泄露就是对象不在GC的掌控之内 下面对象会发生内存泄露现象: 1.没有引用的对象 2.虚,软,弱 引用对象 GC引用的对象指的是 1.JavaStack中引用的对象 2.方法区中静态引用指向的对象 ...

  2. 使用 Apache Tiles 3 构建页面布局

    参考博客:http://aiilive.blog.51cto.com/1925756/1596059Apache Tiles是一个JavaEE应用的页面布局框架.Tiles框架提供了一种模板机制,可以 ...

  3. poj_2479 动态规划

    题目大意 给定一列数,从中选择两个不相交的连续子段,求这两个连续子段和的最大值. 题目分析 典型的M子段和的问题,使用动态规划的方法来解决. f[i][j] 表示将A[1...i] 划分为j个不相交连 ...

  4. keepalive和脑裂问题

    keepalive keepalive起初专门为lvs负载均衡软件设计的,用来管理监控lvs集群系统中各个服务节点的状态,后来又加入了可以实现高可用的vrrp功能. keepalive软件通过vrrp ...

  5. SpringMvc三大组件详解

    SpringMvc框架结构图 处理器映射器:用户请求路径到Controller方法的映射 处理器适配器:根据handler(controlelr类)的开发方式(注解开发/其他开发) 方式的不同区寻找不 ...

  6. js 模拟 select 的 click 事件

    法一. 你可以直接通过修改 select 的 size 属性来实现,但是这样比较丑,很明显:原来: 修改 size: 跟原生比丑在两点: 位置上移了 滚动条出现了 法二. 比较好的实现,就是通过 js ...

  7. 01.ZooKeeper安装和介绍

    1.ZooKeeper安装和启动 1.下载解压ZooKeeper ZooKeeper官方地址:http://zookeeper.apache.org/ 下载当前稳定版本:zookeeper-3.4.6 ...

  8. 160429、nodejs--Socket.IO即时通讯

    动态web 在html5以前,web的设计上并没有考虑过动态,他一直是围绕着文档设计的,我们看以前比较老的网站,基本上都是某一刻用来显示单一的文档的,用户请求一次web页面,获取一个页面,但是随着时间 ...

  9. Struts文件下载(静态)

    前言:在实际的开发中,我们可能需要动态下载和静态下载, 动态下载:例如我上传了一个文件,你想下载,那就必须动态生成下载链接,因为我服务器一开始是不知道我上传的东西是什么,放在那里, 静态下载:比如一些 ...

  10. 剑指Offer——二叉树的深度

    题目描述: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 分析: 二叉树的深度等于其左子树的深度和右子树的深度两个中最大的深 ...