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. leetcode -- Permutations II TODO

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  2. iOS 8出色的跨应用通信效果:解读Action扩展

    本文转载至 http://mobile.51cto.com/iphone-464809.htm 用程序扩展最初于WWDC 2014大会上正式亮相,这是一种将iOS应用程序功能扩展至系统其它组成部分的途 ...

  3. Surface UEFI 菜单显示

    下载 Surface 的恢复映像   https://support.microsoft.com/zh-cn/surfacerecoveryimage UEFI 设置只能在系统启动时进行调整.若要加载 ...

  4. 【BZOJ4231】回忆树 离线+fail树+KMP

    [BZOJ4231]回忆树 Description 回忆树是树. 具体来说,是n个点n-1条边的无向连通图,点标号为1~n,每条边上有一个字符(出于简化目的,我们认为只有小写字母). 对一棵回忆树来说 ...

  5. Java使用Apache POI进行Excel导入和导出

    Manve依赖 <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --> <dependency> ...

  6. 区分兼容IE6/IE7/IE8/IE9/FF的CSS HACK写法

    HACK原理:不同浏览器对各中字符的识别不同 在 CSS中常用特殊字符识别表: (1)*:  IE6+IE7都能识别*,而标准浏览器FF+IE8是不能识别*的; (2)!important: 除IE6 ...

  7. Myeclipse中js总是报错

    1.右键选择 MyEclipse-->Exclude From Validation .2.再右键选择 MyEclipse-->Run Validation 即可.

  8. 微信openid的单脚本获取 将 header 至自身,但是reques参数不同,响应也不同-----“单脚本APP”

    w 0-目的是封装成一个类.方法,方便在不同入口下,比如不是在微信公众号内而是在他人分享的url,获取opeid,且便于路由控制,将路由控制交给且仅交给codeigniter; 1-任何一个网站都可以 ...

  9. Python 名称空间与作用域、闭包与装饰器

    Python 的名称 Python 的名称(Name)是对象的一个标识(Identifier).我们知道,在 Python 里面一切皆对象,名称就是用来引用对象的.说得有点玄乎,我们以例子说明. 例如 ...

  10. Accuracy, Precision, Resolution & Sensitivity

    Instrument manufacturers usually supply specifications for their equipment that define its accuracy, ...