1. 程式人生 > >ABP框架 - 模塊系統

ABP框架 - 模塊系統

PE 接口 sources 進行 over 組合 -c trapper bootstrap

模塊系統介紹

ABP提供了基礎設施功能來構建模塊,並通過組合這些模塊來創建應用。一個模塊可以依賴於另一個模塊。一般來講,一個程序集被認為和定義成一個模塊。如果你的應用包含多個程序集,那麽你可以為每一個程序集都定義一個模塊。

模塊定義

ABP中的一個模塊是由繼承於AbpModule(AbpModule定義在ABP package中)的一個類來定義的。比如我們開發了一個博客模塊,可以被不同的應用程序使用,那麽一個最簡單的博客模塊定義如下:

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

定義模塊的類有一個職責就是通過依賴註入來註冊模塊中的類型,如上代碼所示:

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特性來顯示的定義模塊間的依賴關系,如下所示:

[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擴展方法定義了添加插件模塊源的選項:

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

如果你在插件模塊中定義了MVC / Web API Controllers, ASP.NET將不能檢測到這些Controllers, 要解決這個問題,你需要修改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();
        }
    }
}

附加程序集

在ABP中定義了兩個接口IAssemblyFinder和ITypeFinder,這兩個接口是ABP用來檢測應用中的程序中的程序集和類型的。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的方法了,但是前提條件是MyModule2模塊依賴MyModule1模塊。

模塊配置

ABP中建議使用啟動配置(startup configuration)來配置模塊

模塊生存期

定義模塊的類會被自動註冊為單例

ABP框架 - 模塊系統