ABP提供了基礎設施功能來構建模塊,並經過組合這些模塊來建立應用。一個模塊能夠依賴於另外一個模塊。通常來說,一個程序集被認爲和定義成一個模塊。若是你的應用包含多個程序集,那麼你能夠爲每個程序集都定義一個模塊。web
ABP中的一個模塊是由繼承於AbpModule(AbpModule定義在ABP package中)的一個類來定義的。好比咱們開發了一個博客模塊,能夠被不一樣的應用程序使用,那麼一個最簡單的博客模塊定義以下:c#
public class MyBlogApplicationModule : AbpModule { public override void Initialize() { IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly()); } }
定義模塊的類有一個職責就是經過依賴注入來註冊模塊中的類型,如上代碼所示:api
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
固然,除此以外,它還能夠配置應用程序,實現新的功能等等安全
當應用程序啓動和關閉時,ABP會調用模塊中的一組特定方法PreInitialize、Initialize、PostInitialize、Shutdown。你能夠重寫這些方法來執行特定任務。mvc
ABP是根據模塊之間的依賴順序來執行模塊的這些方法的。例如模塊A依賴於模塊B,那麼模塊B就會在模塊A以前作初始化。當應用程序啓動時,模塊A和模塊B中這些方法的執行順序以下:PreInitialize-B-->PreInitialize-A-->Initialize-B-->Initialize-A-->PostInitialize-B-->PostInitialize-Aapp
當應用程序關閉時,過程與啓動相似,只是執行順序與啓動時是相反的。框架
當啓動時,會首先調用PreInitialize方法,它在模塊初始化以前執行,因此一般會將框架和模塊的配置定義在這裏。同時,一些在依賴注入以前執行的代碼也會寫在這裏。例如你定義一個傳統的類,那麼你須要在這裏調用 IocManager.AddConventionalRegisterer 方法來註冊它。asp.net
在Initialize方法中,會經過依賴注入註冊模塊中定義的類型,通常使用IocManager.RegisterAssemblyByConvention 方法來來註冊,固然也可自定義類型註冊。ide
在啓動過程當中,這是最後一個被調用的方法。在這裏能夠安全的解析一個依賴。函數
在應用關閉時,會調用此方法。
一個模塊能夠依賴於另外一個模塊,你須要使用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, 用於從指定的文件夾中獲取插件模塊。
在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應用程序,咱們能夠重寫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 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)來配置模塊
定義模塊的類會被自動註冊爲單例