搭建基礎(chǔ)結(jié)構(gòu)的ABP解決方案介紹
搭建項(xiàng)目基礎(chǔ)結(jié)構(gòu)
打開(kāi) VS 2019,創(chuàng)建一個(gè)解決方案,然后刪除解決方案的項(xiàng)目,變成空解決方案。本系列教程將使用 AbpBase
來(lái)命名解決方案和項(xiàng)目前綴。
在解決方案中新建一個(gè)解決方案文件夾,名字為 src
,用來(lái)存放項(xiàng)目源碼。
我們將要?jiǎng)?chuàng)建一個(gè)類似下圖這樣的層次結(jié)構(gòu)的解決方案,只是沒(méi)有 HttpApi.Client
,另外.EntityFrameCore
改成了 .Database
。
下面我們來(lái)創(chuàng)建需要的項(xiàng)目結(jié)構(gòu),和了解每一個(gè)項(xiàng)目的作用。
AbpBase.Domain.Shared
此項(xiàng)目是最底層的模塊,且不依賴其他模塊,主要用于定義各種枚舉(enums
)、全局常量(constants
)、靜態(tài)變量(static)、啟動(dòng)依賴配置(options)等。還可以在此為程序設(shè)置一個(gè)標(biāo)準(zhǔn),限制各個(gè)層次的模塊都必須符合此標(biāo)準(zhǔn)的要求。
例如 規(guī)定API 請(qǐng)求的一般參數(shù),字符串長(zhǎng)度不得大于 256 個(gè)字符,我們可以這樣寫(xiě):
public static Whole { public const int MaxLength = 256; } [StringLength(maximumLength:Whole.MaxLength)]
總之,這個(gè)模塊用于定義各種全局的、共享的內(nèi)容(變量、枚舉等),一般不包含服務(wù)。
創(chuàng)建過(guò)程
在解決方案中新建 .NET Standard
項(xiàng)目,名稱為 AbpBase.Domain.Shared
,然后通過(guò) Nuget
添加 Volo.Abp.Core
包,版本為 3.1.2
。
然后新建 一個(gè) AbpBaseDomainSharedModule.cs
文件,其內(nèi)容如下:
using System; using Volo.Abp.Modularity; namespace AbpBase.Domain.Shared { [DependsOn()] public class AbpBaseDomainSharedModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { } } }
在 ABP 項(xiàng)目中,每一個(gè)模塊(項(xiàng)目) 都要?jiǎng)?chuàng)建一個(gè)繼承 AbpModule
的 類,用于聲明此模塊的結(jié)構(gòu)、依賴注入等。
[DependsOn]
是依賴注入標(biāo)記,代表要為模塊注入什么服務(wù),因?yàn)?nbsp;.Domain.Shared
不依賴任何模塊,因此現(xiàn)在先留空,寫(xiě)成 [DependsOn()]
。
AbpBase.Domain
此項(xiàng)目用于定義各種用于傳遞數(shù)據(jù)的類。例如數(shù)據(jù)庫(kù)實(shí)體、用于做參數(shù)傳遞的模型類等。
創(chuàng)建過(guò)程
我們?cè)诮鉀Q方案的src
文件夾,添加一個(gè)新的項(xiàng)目,名字為 AbpBase.Domain
,然后引用 AbpBase.Domain.Shared
項(xiàng)目。
在項(xiàng)目中創(chuàng)建一個(gè) AbpBaseDomainModule.cs
文件,其內(nèi)容如下:
using AbpBase.Domain.Shared; using Volo.Abp.Modularity; namespace AbpBase.Domain { [DependsOn( typeof(AbpBaseDomainSharedModule) )] public class AbpBaseDomainModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { } } }
AbpBase.Domain
依賴于 AbpBase.Domain.Shared
。
AbpBase.Application.Contracts
主要用于定義接口、抽象和 DTO 對(duì)象。這個(gè)模塊用于定義各種服務(wù),但是不提供實(shí)現(xiàn)。
創(chuàng)建過(guò)程
在解決方案的 src
文件夾,新建一個(gè) AbpBase.Application.Contracts
項(xiàng)目,然后添加 AbpBase.Domain
項(xiàng)目引用。
在項(xiàng)目里新建一個(gè) AbpBaseApplicationContractsModule
文件,其內(nèi)容如下:
using AbpBase.Domain; using Volo.Abp.Modularity; namespace AbpBase.Application.Contracts { [DependsOn( typeof(AbpBaseDomainModule) )] public class AbpBaseApplicationContractsModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { } } }
AbpBase.Database
此模塊用于配置和定義 EFCore、Freesql 等 ORM,還有倉(cāng)儲(chǔ)等,主要是處理數(shù)據(jù)庫(kù)相關(guān)的代碼。
創(chuàng)建過(guò)程
在解決方案 的 src
目錄新建一個(gè) AbpBase.Database
項(xiàng)目,然后添加 AbpBase.Domain
項(xiàng)目引用。
在項(xiàng)目中新建一個(gè) AbpBaseDatabaseModule
文件,其內(nèi)容如下:
using AbpBase.Domain; using Volo.Abp.Modularity; namespace AbpBase.Database { [DependsOn( typeof(AbpBaseDomainModule) )] public class AbpBaseDatabaseModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { } } }
ABP 里面默認(rèn)集成了 EFCore
,所以我們可以直接拿來(lái)使用,這里我們先不處理數(shù)據(jù)庫(kù)相關(guān)的東西,但是先提前配好依賴注入。
在 Nuget 管理器中,添加下面四個(gè)包,版本都是 3.1.2 :
Volo.Abp.EntityFrameworkCore Volo.Abp.EntityFrameworkCore.MySQL Volo.Abp.EntityFrameworkCore.Sqlite Volo.Abp.EntityFrameworkCore.SqlServer
然后將 AbpBaseDatabaseModule.cs
文件的內(nèi)容修改成如下內(nèi)容:
using AbpBase.Domain; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.MySQL; using Volo.Abp.EntityFrameworkCore.Sqlite; using Volo.Abp.EntityFrameworkCore.SqlServer; using Volo.Abp.Modularity; namespace AbpBase.Database { [DependsOn( typeof(AbpBaseDomainModule), typeof(AbpEntityFrameworkCoreModule), typeof(AbpEntityFrameworkCoreSqliteModule), typeof(AbpEntityFrameworkCoreSqlServerModule), typeof(AbpEntityFrameworkCoreMySQLModule) )] public class AbpBaseDatabaseModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { } } }
這樣,我們的項(xiàng)目將可以支持三種數(shù)據(jù)庫(kù)的使用。
AbpBase.Application
此用于實(shí)現(xiàn)接口、編寫(xiě)各種服務(wù)。
創(chuàng)建過(guò)程
在解決方案的 src
文件夾,新建一個(gè) AbpBase.Application
項(xiàng)目,然后添加 AbpBase.Application.Contracts
、 AbpBase.Database
項(xiàng)目引用。
在項(xiàng)目里創(chuàng)建一個(gè) AbpBaseApplicationModule.cs
文件,其文件內(nèi)容如下:
using AbpBase.Application.Contracts; using AbpBase.Database; using AbpBase.Domain; using Volo.Abp.Modularity; namespace AbpBase.Application { [DependsOn( typeof(AbpBaseDomainModule), typeof(AbpBaseApplicationContractsModule), typeof(AbpBaseDatabaseModule) )] public class AbpBaseApplicationModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { } } }
AbpBase.HttpApi
此項(xiàng)目用于編寫(xiě) API 控制器。
創(chuàng)建過(guò)程
創(chuàng)建 一個(gè) .NET Core 控制臺(tái)項(xiàng)目,名字為 AbpBase.HttpApi
,通過(guò) Nuget 添加 Volo.Abp.AspNetCore.Mvc
包,版本為 3.1.2。
然后添加 AbpBase.Application.Contracts
和 AbpBase.Application
兩個(gè)項(xiàng)目引用。
在項(xiàng)目里面創(chuàng)建一個(gè) AbpBaseHttpApiModule.cs
文件,其內(nèi)容如下:
using AbpBase.Application; using AbpBase.Application.Contracts; using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.Modularity; namespace AbpBase.HttpApi { [DependsOn( typeof(AbpAspNetCoreMvcModule), typeof(AbpBaseApplicationModule), typeof(AbpBaseApplicationContractsModule) )] public class AbpBaseHttpApiModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { Configure<AbpAspNetCoreMvcOptions>(options => { options .ConventionalControllers .Create(typeof(AbpBaseHttpApiModule).Assembly, opts => { opts.RootPath = "api/1.0"; }); }); } } }
上面,模塊的 ConfigureServices
函數(shù)里面,創(chuàng)建了 API 服務(wù)。
AbpBase.Web
此模塊是最上層的模塊,用于提供 UI 與用戶交互、權(quán)限控制、提供啟動(dòng)配置信息、控制程序運(yùn)行等。
創(chuàng)建過(guò)程
在解決方案的 src
文件夾,新建一個(gè) AbpBase.Web
項(xiàng)目,項(xiàng)目為 ASP.NET Core
程序,并且創(chuàng)建模板為“空”。
通過(guò) Nuget 管理器添加 Volo.Abp.Autofac
,版本為 3.1.2,然后添加 AbpBase.Application
和 AbpBase.HttpApi
項(xiàng)目引用。
在項(xiàng)目里面創(chuàng)建 AbpBaseWebModule.cs
文件,其內(nèi)容如下:
using AbpBase.Application; using AbpBase.HttpApi; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Hosting; using Volo.Abp; using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.Modularity; namespace AbpBase.Web { [DependsOn( typeof(AbpBaseApplicationModule), typeof(AbpAspNetCoreMvcModule), typeof(AbpBaseHttpApiModule) )] public class AbpBaseWebModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { } public override void OnApplicationInitialization( ApplicationInitializationContext context) { var app = context.GetApplicationBuilder(); var env = context.GetEnvironment(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); } app.UseStaticFiles(); app.UseRouting(); app.UseConfiguredEndpoints(); } } }
在 Program.cs
文件中 ,加上 .UseAutofac()
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }).UseAutofac();
將 Startup.cs
的內(nèi)容 改為:
using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; namespace AbpBase.Web { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddApplication<AbpBaseWebModule>(); } public void Configure(IApplicationBuilder app) { app.InitializeApplication(); } } }
完成上面的步驟后,你將得到一個(gè)可以啟動(dòng)的、具有基礎(chǔ)結(jié)構(gòu)的 ABP(WEB) 應(yīng)用,你可以添加一個(gè) API 來(lái)進(jìn)行測(cè)試訪問(wèn)。
在 AbpBase.HttpApi
項(xiàng)目中,創(chuàng)建一個(gè) COntrollers
目錄,再添加一個(gè) API 控制器,其內(nèi)容如下:
using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Volo.Abp.AspNetCore.Mvc; namespace AbpBase.Web.Controllers { [ApiController] public class TestController : AbpController { [HttpGet("/T")] public string MyWebApi() { return "應(yīng)用啟動(dòng)成功!"; } } }
然后啟動(dòng)程序,訪問(wèn) https://localhost:5001/T,可以發(fā)現(xiàn)頁(yè)面顯示了字符串,則測(cè)試成功。
當(dāng)然,這只是一個(gè)非常簡(jiǎn)單的結(jié)構(gòu),我們還需要添加項(xiàng)目跨域、授權(quán)驗(yàn)證、依賴注入、swagger 、數(shù)據(jù)庫(kù)訪問(wèn)等一系列的服務(wù),后面我們將通過(guò)從易到難、逐步求精的方法來(lái)學(xué)習(xí) ABP 框架和架設(shè)一個(gè)完整的實(shí)踐項(xiàng)目!
下面介紹一下上面模塊中出現(xiàn)的一些代碼結(jié)構(gòu)。
關(guān)于ABP和代碼解疑
完成上面的步驟后,相信你應(yīng)該對(duì) ABP 項(xiàng)目有了大致的認(rèn)識(shí),下面我們來(lái)介紹一下 ABP 中的一些概念以及前面出現(xiàn)到的一些代碼解析。
模塊
我們看一下 ABP 官網(wǎng)中關(guān)于 ABP 的介紹:
ABP 框架提供的設(shè)計(jì)旨在支持構(gòu)建完全模塊化的應(yīng)用程序和系統(tǒng)
前面我們建立了 7 個(gè)項(xiàng)目,相信大家已經(jīng)體驗(yàn)到了模塊化開(kāi)發(fā)的過(guò)程。
ABP 模塊化,就是將每個(gè)項(xiàng)目作為一個(gè)模塊,然后每個(gè)模塊中需要定義一個(gè)繼承 AbpModule
的類,最終集成到上層模塊中。
[DependsOn]
一個(gè)模塊要使用另一個(gè)模塊時(shí),通過(guò) [DependsOn]
特性來(lái)引用需要的模塊。
配置服務(wù)和管道
繼承 AbpModule
的類型,可以使用 ConfigureServices
來(lái)配置服務(wù),如依賴注入、數(shù)據(jù)庫(kù)配置、跨域等,OnApplicationInitialization
則用來(lái)配置中間件管道。
當(dāng)然,這兩個(gè)函數(shù)都可以不寫(xiě),直接寫(xiě)個(gè)空的 Module
:
[DependsOn( typeof(AbpBaseDomainSharedModule) )] public class AbpBaseDomainModule : AbpModule { }
模塊如何關(guān)聯(lián)
首先,每個(gè)模塊都需要定義一個(gè)類來(lái)繼承 AbpModule
,然后一個(gè)模塊要使用另一個(gè)模塊,則通過(guò) [DependsOn]
來(lái)聲明引用。
在本教程的解決方案結(jié)構(gòu)中, AbpBase.Web
是最上層的項(xiàng)目,他依賴了三個(gè)模塊:
[DependsOn( typeof(AbpBaseApplicationModule), typeof(AbpBaseHttpApiModule), typeof(AbpAspNetCoreMvcModule) )]
而 AbpBaseApplicationModule
模塊又使用了其他模塊,這就形成了一個(gè)引用鏈,讀者可以看看文章開(kāi)頭的圖片。
引用鏈形成后,程序啟動(dòng)時(shí),會(huì)順著這個(gè)鏈,從最底層的模塊開(kāi)始初始化。這個(gè)初始化鏈會(huì)依次調(diào)用模塊的 ConfigureServices
函數(shù),為程序逐漸配置服務(wù)。
Domain.Shared -> Domain -> Application.Contras -> ....
你可以在每個(gè) Module
的 ConfigureServices
函數(shù)中打印控制臺(tái)信息,然后啟動(dòng)程序進(jìn)行測(cè)試,看看打印順序。
源碼地址:https://github.com/whuanle/AbpBaseStruct
本教程結(jié)果代碼位置:https://github.com/whuanle/AbpBaseStruct/tree/master/src/1/AbpBase
到此這篇關(guān)于搭建基礎(chǔ)結(jié)構(gòu)的ABP解決方案的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解ABP框架中的數(shù)據(jù)過(guò)濾器與數(shù)據(jù)傳輸對(duì)象的使用
ABP框架是一個(gè)基于ASP.NET的Web開(kāi)發(fā)框架,這里我們來(lái)詳解ABP框架中的數(shù)據(jù)過(guò)濾器與數(shù)據(jù)傳輸對(duì)象的使用,需要的朋友可以參考下2016-06-06.Net行為型設(shè)計(jì)模式之訪問(wèn)者模式(Visitor)
這篇文章介紹了.Net行為型設(shè)計(jì)模式之訪問(wèn)者模式(Visitor),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05.Net行為型設(shè)計(jì)模式之迭代器模式(Iterator)
這篇文章介紹了.Net行為型設(shè)計(jì)模式之迭代器模式(Iterator),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05.Net行為型設(shè)計(jì)模式之狀態(tài)模式(State)
這篇文章介紹了.Net行為型設(shè)計(jì)模式之狀態(tài)模式(State),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05