淺入ABP(1):搭建基礎結構的 ABP 解決方案


淺入ABP(1):搭建基礎結構的 ABP 解決方案

版權護體©作者:痴者工良,微信公眾號轉載文章需要 《NCC開源社區》同意。

源碼地址:https://github.com/whuanle/AbpBaseStruct

本教程結果代碼位置:https://github.com/whuanle/AbpBaseStruct/tree/master/src/1/AbpBase

這里是淺入 ABP 系列的第一章,我們將學習如果搭建一個極簡的 ABP 項目結構,后面我們通過這個結構,一步步來講解、一步步開發和完善。

ABP 系列的第一篇,請各位多多支持~

搭建項目基礎結構

打開 VS 2019,創建一個解決方案,然后刪除解決方案的項目,變成空解決方案。本系列教程將使用 AbpBase 來命名解決方案和項目前綴。

在解決方案中新建一個解決方案文件夾,名字為 src,用來存放項目源碼。

空解決方案

我們將要創建一個類似下圖這樣的層次結構的解決方案,只是沒有 HttpApi.Client ,另外.EntityFrameCore 改成了 .Database

解決方案結構

下面我們來創建需要的項目結構,和了解每一個項目的作用。

AbpBase.Domain.Shared

此項目是最底層的模塊,且不依賴其他模塊,主要用於定義各種枚舉(enums)、全局常量(constants)、靜態變量(static)、啟動依賴配置(options)等。還可以在此為程序設置一個標准,限制各個層次的模塊都必須符合此標准的要求。

例如 規定API 請求的一般參數,字符串長度不得大於 256 個字符,我們可以這樣寫:

public static Whole
{
	public const int MaxLength = 256;
}

[StringLength(maximumLength:Whole.MaxLength)]

總之,這個模塊用於定義各種全局的、共享的內容(變量、枚舉等),一般不包含服務。

創建過程

在解決方案中新建 .NET Standard 項目,名稱為 AbpBase.Domain.Shared,然后通過 Nuget 添加 Volo.Abp.Core 包,版本為 3.1.2

shared

然后新建 一個 AbpBaseDomainSharedModule.cs 文件,其內容如下:

using System;
using Volo.Abp.Modularity;

namespace AbpBase.Domain.Shared
{
    [DependsOn()]
    public class AbpBaseDomainSharedModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
        }
    }
}

在 ABP 項目中,每一個模塊(項目) 都要創建一個繼承 AbpModule 的 類,用於聲明此模塊的結構、依賴注入等。

[DependsOn] 是依賴注入標記,代表要為模塊注入什么服務,因為 .Domain.Shared 不依賴任何模塊,因此現在先留空,寫成 [DependsOn()]

AbpBase.Domain

此項目用於定義各種用於傳遞數據的類。例如數據庫實體、用於做參數傳遞的模型類等。

創建過程

我們在解決方案的src 文件夾,添加一個新的項目,名字為 AbpBase.Domain,然后引用 AbpBase.Domain.Shared 項目。

在項目中創建一個 AbpBaseDomainModule.cs 文件,其內容如下:

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 對象。這個模塊用於定義各種服務,但是不提供實現。

創建過程

在解決方案的 src 文件夾,新建一個 AbpBase.Application.Contracts 項目,然后添加 AbpBase.Domain 項目引用。

在項目里新建一個 AbpBaseApplicationContractsModule 文件,其內容如下:

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,還有倉儲等,主要是處理數據庫相關的代碼。

創建過程

在解決方案 的 src 目錄新建一個 AbpBase.Database 項目,然后添加 AbpBase.Domain 項目引用。

在項目中新建一個 AbpBaseDatabaseModule 文件,其內容如下:

using AbpBase.Domain;
using Volo.Abp.Modularity;

namespace AbpBase.Database
{
    [DependsOn(
  	 typeof(AbpBaseDomainModule)
    )]
    public class AbpBaseDatabaseModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {

        }
    }
}

ABP 里面默認集成了 EFCore ,所以我們可以直接拿來使用,這里我們先不處理數據庫相關的東西,但是先提前配好依賴注入。

在 Nuget 管理器中,添加下面四個包,版本都是 3.1.2 :

Volo.Abp.EntityFrameworkCore
Volo.Abp.EntityFrameworkCore.MySQL
Volo.Abp.EntityFrameworkCore.Sqlite
Volo.Abp.EntityFrameworkCore.SqlServer

然后將 AbpBaseDatabaseModule.cs 文件的內容修改成如下內容:

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)
        {
        }
    }
}

這樣,我們的項目將可以支持三種數據庫的使用。

AbpBase.Application

此用於實現接口、編寫各種服務。

創建過程

在解決方案的 src 文件夾,新建一個 AbpBase.Application 項目,然后添加 AbpBase.Application.ContractsAbpBase.Database 項目引用。

在項目里創建一個 AbpBaseApplicationModule.cs 文件,其文件內容如下:

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

此項目用於編寫 API 控制器。

創建過程

創建 一個 .NET Core 控制台項目,名字為 AbpBase.HttpApi,通過 Nuget 添加 Volo.Abp.AspNetCore.Mvc 包,版本為 3.1.2。

然后添加 AbpBase.Application.ContractsAbpBase.Application 兩個項目引用。

在項目里面創建一個 AbpBaseHttpApiModule.cs 文件,其內容如下:

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 函數里面,創建了 API 服務。

AbpBase.Web

此模塊是最上層的模塊,用於提供 UI 與用戶交互、權限控制、提供啟動配置信息、控制程序運行等。

創建過程

在解決方案的 src 文件夾,新建一個 AbpBase.Web 項目,項目為 ASP.NET Core 程序,並且創建模板為“空”。

通過 Nuget 管理器添加 Volo.Abp.Autofac,版本為 3.1.2,然后添加 AbpBase.ApplicationAbpBase.HttpApi 項目引用。

在項目里面創建 AbpBaseWebModule.cs 文件,其內容如下:

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 的內容 改為:

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();
        }
    }
}

完成上面的步驟后,你將得到一個可以啟動的、具有基礎結構的 ABP(WEB) 應用,你可以添加一個 API 來進行測試訪問。

AbpBase.HttpApi 項目中,創建一個 COntrollers 目錄,再添加一個 API 控制器,其內容如下:

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 "應用啟動成功!";
        }
    }
}

然后啟動程序,訪問 https://localhost:5001/T,可以發現頁面顯示了字符串,則測試成功。

當然,這只是一個非常簡單的結構,我們還需要添加項目跨域、授權驗證、依賴注入、swagger 、數據庫訪問等一系列的服務,后面我們將通過從易到難、逐步求精的方法來學習 ABP 框架和架設一個完整的實踐項目!

下面介紹一下上面模塊中出現的一些代碼結構。

關於ABP和代碼解疑

完成上面的步驟后,相信你應該對 ABP 項目有了大致的認識,下面我們來介紹一下 ABP 中的一些概念以及前面出現到的一些代碼解析。

模塊

我們看一下 ABP 官網中關於 ABP 的介紹:

ABP 框架提供的設計旨在支持構建完全模塊化的應用程序和系統

前面我們建立了 7 個項目,相信大家已經體驗到了模塊化開發的過程。

ABP 模塊化,就是將每個項目作為一個模塊,然后每個模塊中需要定義一個繼承 AbpModule 的類,最終集成到上層模塊中。

[DependsOn]

一個模塊要使用另一個模塊時,通過 [DependsOn] 特性來引用需要的模塊。

配置服務和管道

繼承 AbpModule 的類型,可以使用 ConfigureServices 來配置服務,如依賴注入、數據庫配置、跨域等,OnApplicationInitialization 則用來配置中間件管道。

當然,這兩個函數都可以不寫,直接寫個空的 Module

    [DependsOn(
        typeof(AbpBaseDomainSharedModule)
        )]
    public class AbpBaseDomainModule : AbpModule
    {
    }

模塊如何關聯

首先,每個模塊都需要定義一個類來繼承 AbpModule ,然后一個模塊要使用另一個模塊,則通過 [DependsOn] 來聲明引用。

在本教程的解決方案結構中, AbpBase.Web 是最上層的項目,他依賴了三個模塊:

    [DependsOn(
        typeof(AbpBaseApplicationModule),
        typeof(AbpBaseHttpApiModule),
        typeof(AbpAspNetCoreMvcModule)
        )]

AbpBaseApplicationModule 模塊又使用了其他模塊,這就形成了一個引用鏈,讀者可以看看文章開頭的圖片。

引用鏈形成后,程序啟動時,會順着這個鏈,從最底層的模塊開始初始化。這個初始化鏈會依次調用模塊的 ConfigureServices 函數,為程序逐漸配置服務。

Domain.Shared -> Domain -> Application.Contras -> ....

你可以在每個 ModuleConfigureServices 函數中打印控制台信息,然后啟動程序進行測試,看看打印順序。

對於 ABP 的介紹,大家可以看文檔,這里就不搬文檔的內容了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM