前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ABP框架 - 模块系统

ABP框架 - 模块系统

作者头像
我思故我在
发布2018-05-11 11:58:23
1.4K0
发布2018-05-11 11:58:23
举报
文章被收录于专栏:我思故我在

模块系统介绍

ABP提供了基础设施功能来构建模块,并通过组合这些模块来创建应用。一个模块可以依赖于另一个模块。一般来讲,一个程序集被认为和定义成一个模块。如果你的应用包含多个程序集,那么你可以为每一个程序集都定义一个模块。

模块定义

ABP中的一个模块是由继承于AbpModule(AbpModule定义在ABP package中)的一个类来定义的。比如我们开发了一个博客模块,可以被不同的应用程序使用,那么一个最简单的博客模块定义如下:

代码语言:javascript
复制
public class MyBlogApplicationModule : AbpModule
{
    public override void Initialize()
    {
        IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
    }
}

定义模块的类有一个职责就是通过依赖注入来注册模块中的类型,如上代码所示:

代码语言:javascript
复制
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());

当然,除此之外,它还可以配置应用程序,实现新的功能等等

模块的生命周期

当应用程序启动和关闭时,ABP会调用模块中的一组特定方法PreInitialize、Initialize、PostInitialize、Shutdown。你可以重写这些方法来执行特定任务。

ABP是根据模块之间的依赖顺序来执行模块的这些方法的。例如模块A依赖于模块B,那么模块B就会在模块A之前做初始化。当应用程序启动时,模块A和模块B中这些方法的执行顺序如下:PreInitialize-B-->PreInitialize-A-->Initialize-B-->Initialize-A-->PostInitialize-B-->PostInitialize-A

当应用程序关闭时,过程与启动类似,只是执行顺序与启动时是相反的。

PreInitialize

当启动时,会首先调用PreInitialize方法,它在模块初始化之前执行,所以通常会将框架和模块的配置定义在这里。同时,一些在依赖注入之前执行的代码也会写在这里。例如你定义一个传统的类,那么你需要在这里调用 IocManager.AddConventionalRegisterer 方法来注册它。

Initialize

在Initialize方法中,会通过依赖注入注册模块中定义的类型,一般使用IocManager.RegisterAssemblyByConvention 方法来来注册,当然也可自定义类型注册。

PostInitialize

在启动过程中,这是最后一个被调用的方法。在这里可以安全的解析一个依赖。

Shutdown

在应用关闭时,会调用此方法。

模块依赖

一个模块可以依赖于另一个模块,你需要使用DependsOn特性来显示的定义模块间的依赖关系,如下所示:

代码语言:javascript
复制
[DependsOn(typeof(MyBlogCoreModule))]
public class MyBlogApplicationModule : AbpModule
{
    public override void Initialize()
    {
        IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
    }
}

在这里,我们定义MyBlogApplicationModule模块依赖于MyBlogCoreModule模块,并且MyBlogCoreModule模块要在MyBlogApplicationModule模块之前进行初始化。

ABP在启动模块中,自动的解析模块之间的依赖关系并初始化模块。启动模块是最后一个被初始化的模块。

插件模块

ABP可以在启动模块中检测、加载模块集,也可以动态的加载模块,这些动态加载的模块就称之为插件模块。

在动态加载模块时,要指定插件模块的源,在AbpBootstrapper类中定义了一个属性PlugInSources, 就是用来指定插件模块的源。任何一个实现了IPlugInSource接口的类都可以用来定义插件模块的源。

在ABP中提供了一个默认实现PlugInFolderSource, 用于从指定的文件夹中获取插件模块。

ASP.NET CORE

在ABP ASP.NET Core模块的Startup类中,ABP为AddAbp扩展方法定义了添加插件模块源的选项:

代码语言:javascript
复制
services.AddAbp<MyStartupModule>(options =>
{
    options.PlugInSources.Add(new FolderPlugInSource(@"C:\MyPlugIns"));
});

也可以使用AddFolder扩展方法

代码语言:javascript
复制
services.AddAbp<MyStartupModule>(options =>
{
    options.PlugInSources.AddFolder(@"C:\MyPlugIns");
});

ASP.NET MVC, Web API

如果是ASP.NET MVC应用程序,我们可以重写global.asax中的Application_Start方法来添加插件模块的源:

代码语言:javascript
复制
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

如果你在插件模块中定义了MVC / Web API Controllers, ASP.NET将不能检测到这些Controllers, 要解决这个问题,你需要修改global.asax代码文件如下:

代码语言:javascript
复制
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();
        }
    }
}

附加程序集

在ABP中定义了两个接口IAssemblyFinder和ITypeFinder,这两个接口是ABP用来检测应用中的程序中的程序集和类型的。ABP为这两个接口提供了默认实现,在默认实现中,仅仅从上述模块(通过启动模块定义的模块依赖解析出的模块,以及插件模块)中来查找程序集和类型。如果想添加其他程序集,可以重写GetAdditionalAssemblies方法。

模块中的自定义方法

在模块中可以定义自定义方法,模块中的自定义方法可以被其他依赖的模块调用。假设MyModule2模块依赖MyModule1模块,并且想在PreInitialize方法中调用MyModule1模块的自定义方法,如下代码所示:

代码语言:javascript
复制
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模块。

模块配置

ABP中建议使用启动配置(startup configuration)来配置模块

模块生存期

定义模块的类会被自动注册为单例

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-05-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 模块系统介绍
  • 模块定义
  • 模块的生命周期
    • PreInitialize
      • Initialize
        • PostInitialize
          • Shutdown
          • 模块依赖
          • 插件模块
            • ASP.NET CORE
              • ASP.NET MVC, Web API
                • 插件模块中的Controllers
                • 附加程序集
                • 模块中的自定义方法
                • 模块配置
                • 模块生存期
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档