大家好,我是刚子。
今天咱们聊聊 ABP vNext。
大部分企业级项目(ERP、CRM、OA、电商后台)都有着相似的底层需求:
-
用户登录 + 权限控制,永远有一套。你得写角色、写权限、写菜单。
-
审计日志,谁在什么时候操作了什么,得有。
-
多租户,同一个系统服务多个客户,数据还不能混,得有。
-
数据访问,写实体、写仓储、写增删改查,得有。
-
定时任务,每天凌晨跑个报表、发个通知,得有。
这些功能需求——认证授权、审计日志、多租户支持、缓存、本地化、异常处理——在 ABP 里面全部内置好了,框架自带的功能模块,你拿来就能用。
说白了,ABP就是帮你把企业级应用里“重复的那60%”全都搞定,你只需要往上摞业务逻辑就行了。
一、为什么你需要 ABP?
大部分企业级项目(ERP、CRM、OA、电商后台)都有着相似的底层需求:
用户登录 + 权限控制,永远有一套。你得写角色、写权限、写菜单。审计日志,谁在什么时候操作了什么,得有。多租户,同一个系统服务多个客户,数据还不能混,得有。数据访问,写实体、写仓储、写增删改查,得有。定时任务,每天凌晨跑个报表、发个通知,得有。
这些功能需求——认证授权、审计日志、多租户支持、缓存、本地化、异常处理——在 ABP 里面全部内置好了,框架自带的功能模块,你拿来就能用。
说白了,ABP就是帮你把企业级应用里“重复的那60%”全都搞定,你只需要往上摞业务逻辑就行了。
二、ABP vNext 是什么
ABP vNext(全称:ASP.NET Boilerplate Next)是一个基于 ASP.NET Core 的开源企业级应用框架,由土耳其开发者Volkan Ceylan主导开发。
这个项目最早是2013年左右在社区里开始做的。为什么要做它?老ABP(ASP.NET Boilerplate)跑在.NET Framework上,很多技术已经被时代淘汰了。于是作者干脆把底层推到.NET Core技术栈上重新设计和实现,这就有了现在的ABP vNext。
ABP vNext不是一个简单的NuGet包,而是一整套解决方案——从底层架构到顶层应用模块,从代码生成工具到文档体系都有了。
三、ABP 的核心功能:能帮你省掉哪些事?
刚子给你列一个最核心的功能清单:
-
模块化开发:应用程序拆成独立的功能模块(用户模块、订单模块、支付模块),每个模块可以独立开发、独立部署、甚至复用。团队可以并行开发,互不干扰。
-
领域驱动设计(DDD)支持:原生支持多变的复杂业务场景,内置实体、值对象、聚合根、仓储、领域服务等DDD核心概念。
-
开箱即用的认证授权:用户登录、角色权限、策略控制、JWT、OAuth2一键集成。
-
多租户:一行配置开启多租户支持,同一个系统服务多个客户,数据自动隔离。可共享数据库,也可独立数据库,灵活可控。
-
审计日志:自动记录“谁在什么时候改了什么东西”,无需手写任何代码。
-
数据访问全覆盖:默认支持 EF Core 和 MongoDB,内置通用仓储模式(
IRepository<TEntity, TKey>),CRUD代码量大幅减少。 -
统一异常处理:框架提供全局异常过滤器,自动返回标准化响应(如
ProblemDetails),不用再重复写try-catch了。
有同行做过测算:这些基础设施类功能加起来,通常要占掉一个项目大约60%的开发周期。
ABP把这些全部内置好了。你接手一个新项目,第一天不用搭架构、配权限、写审计日志,直接动手写业务代码就行了。
四、ABP 的架构是怎样的?
很多新手刚接触ABP时,被一堆分层概念“领域层、应用层、基础设施层、表现层”搞晕了。
刚子用图书商城这个大家熟悉的场景讲清楚这四层在干嘛:
-
领域层(Domain):放“核心业务规则”。比如“库存数量不能为负数”这个规则,就放在领域层。定义Book实体、BookManager领域服务,确保业务逻辑不会散落到各处。
-
应用层(Application):写“应用服务”,编排业务流程,但不包含核心业务规则。比如“创建图书+同步库存”的流程放在BookAppService里。它调用领域层完成具体操作,但不参与库存不能为负的判断。
-
基础设施层(Infrastructure):管技术实现。比如用EF Core实现IBookRepository接口,跟数据库打交道,上层不关心用的是SQL Server还是MySQL。
-
表现层(Presentation):用户能看到的界面或API端点。比如BookController提供“查询图书”“新增图书”的HTTP接口。
目录结构也是按这个分好层了的:
-
MyProject.Domain:存放实体对象和领域逻辑。 -
MyProject.Application:存放应用服务(业务接口)。 -
MyProject.EntityFrameworkCore:数据访问实现。 -
MyProject.HttpApi.Host:Web API 启动项目。
ABP已经帮你划好了这四层的目录结构和依赖关系,你只需按对应的层写代码即可。
五、5分钟跑起第一个ABP项目
心动不如行动,直接上手跑一个。
你需要在电脑上安装好以下工具:
-
.NET SDK 6.0+:核心运行环境,命令行执行
dotnet --version检查一下。 -
Node.js:前端依赖,推荐LTS版本。
-
数据库:SQL Server / MySQL / PostgreSQL 任选一个。刚子示例用SQL Server。
-
IDE:Visual Studio 2022 或 JetBrains Rider 都可以。
Step 1:安装 ABP CLI
在命令行粘贴以下代码,按回车执行:
bash
dotnet tool install -g Volo.Abp.Cli
安装完成后验证一下版本:
bash
abp --version
显示类似 ABP CLI 9.x.x 的结果,说明安装成功。
Step 2:创建项目
用ABP CLI创建名为“book-store”的应用程序项目:
bash
abp new book-store -t app
-t app表示生成「前后端分离模式」的应用程序模板,后端基于ASP.NET Core Web API,前端默认是Angular。当然你也可以换成-t module生成独立模块,或者选-t mvc生成包含MVC界面的项目。
执行成功后,项目结构大概是这样的:
bash
book-store/ ├── aspnet-core/ # 后端 C# 项目 │ ├── src/ # 源代码 │ │ ├── book-store.Domain # 实体+领域逻辑 │ │ ├── book-store.Application # 应用服务 │ │ ├── book-store.EntityFrameworkCore # EF Core 数据访问 │ │ ├── book-store.HttpApi # API 接口定义 │ │ └── book-store.HttpApi.Host # Web API 启动项目 │ └── test/ # 单元测试项目 ├── angular/ # 前端 Angular 项目 └── vue/ # 前端 Vue 项目(如果选了Vue)
Step 3:配置数据库连接
找到 aspnet-core/src/book-store.HttpApi.Host/appsettings.json 文件,修改ConnectionStrings节点内的Default连接字符串为实际地址。
json
"ConnectionStrings": {
"Default": "Server=127.0.0.1;Database=BookStoreDb;User Id=sa;Password=你的密码;"
}
Step 4:初始化数据库
在 aspnet-core/src/book-store.HttpApi.Host 目录下执行以下命令:
bash
dotnet ef database update
ABP会自动创建所有需要的数据库表(用户表、角色表、权限表、租户表、审计日志表、设置表等),开发者不需要手动建表。
Step 5:启动后端
在同一个HttpApi.Host目录下,执行:
bash
dotnet run
默认监听 https://localhost:44367 或类似端口。用浏览器访问 https://localhost:44367/swagger,看到Swagger文档页面,说明API服务已经启动成功了。
Step 6:启动前端(可选)
如果要体验完整的带前端页面的系统,可以启动前端项目:
bash
cd angular # 或 vue npm install npm run serve
默认账号为 admin / 1q2w3E*,登录后可以看到一个功能完备的后台管理模板,用户管理、角色管理、菜单管理、审计日志等界面都有了。
六、添加第一个业务模块:图书管理
下面通过一个图书管理模块的实例,完整走一遍ABC的四个步骤:实体→仓储→应用服务→API端点。
在 Domain 层定义实体
csharp
using System;
using Volo.Abp.Domain.Entities.Auditing;
namespace book_store.Books
{
// 继承 AuditedAggregateRoot 自动带上创建人/修改人/创建时间/修改时间
public class Book : AuditedAggregateRoot<Guid>
{
public string Name { get; set; }
public string Author { get; set; }
public decimal Price { get; set; }
public int Stock { get; set; }
}
}
继承 AuditedAggregateRoot<Guid>最大的好处就是:不用自己写CreatedAt、CreatorId、LastModifiedAt这些审计字段了,ABP会自动帮你处理。
在 Infrastructure 添加 DbContext 映射
csharp
using Microsoft.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using book_store.Books;
namespace book_store.EntityFrameworkCore
{
public static class BookStoreDbContextModelCreatingExtensions
{
public static void ConfigureBook(this ModelBuilder builder)
{
builder.Entity<Book>(b =>
{
b.ToTable("AppBooks");
b.ConfigureByConvention(); // 按ABP规范配置(软删除、审计等)
b.Property(x => x.Name).IsRequired().HasMaxLength(128);
b.Property(x => x.Author).HasMaxLength(64);
b.Property(x => x.Price).HasColumnType("decimal(18,2)");
});
}
}
}
在 Application.Contracts 创建 DTO 和接口(这一步在项目创建时可选,框架通常已生成模板,按实际需要调整即可)
csharp
using System;
using Volo.Abp.Application.Dtos;
namespace book_store.Books
{
public class BookDto : AuditedEntityDto<Guid>
{
public string Name { get; set; }
public string Author { get; set; }
public decimal Price { get; set; }
public int Stock { get; set; }
}
}
csharp
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
namespace book_store.Books
{
public interface IBookAppService : ICrudAppService<BookDto, Guid>
{
Task DecreaseStockAsync(Guid id, int quantity);
}
}
在 Application 层实现应用服务
ABP提供的CrudAppService基类已经包含了GetListAsync、CreateAsync、UpdateAsync、DeleteAsync这五个基础的CRUD方法。大部分业务场景下,刚子建议优先继承CrudAppService,直接复用框架生成的代码,不要重复写。
csharp
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
namespace book_store.Books
{
public class BookAppService :
CrudAppService<Book, BookDto, Guid, PagedAndSortedResultRequestDto>,
IBookAppService
{
public BookAppService(IRepository<Book, Guid> repository)
: base(repository)
{
}
public async Task DecreaseStockAsync(Guid id, int quantity)
{
var book = await Repository.GetAsync(id);
if (book.Stock < quantity)
{
throw new Exception("库存不足");
}
book.Stock -= quantity;
await Repository.UpdateAsync(book);
}
}
}
几行代码,Create、Update、Delete、GetList、Get这五个标准API就全都有了。加了一个DecreaseStockAsync做扣库存业务——这个Repository就是框架内置的通用仓储基类,提供标准的增删改查方法,不用手写Insert、Update、Delete这些基础SQL代码了。
暴露 API 端点
在 HttpApi 项目中添加控制器。但实际上,ABP对应用服务有自动API约定——只要继承CrudAppService之类的基类,或者类名以AppService结尾,框架会自动把它暴露成HTTP端点,路径默认是/api/app/book。
刚子大白话:在实际项目中,Book换成你的业务实体名称,CreateUpdateBookDto对应了前端传过来的数据结构,代码生成器(ABP Suite)帮你生成这些模板后,你只需要修改几个字段名和业务约束条件,API就出来了。不需要手写Controller、Service、Repository三层代码。
小结
ABP vNext不是“银弹”,也没法帮你写代码。但它的定位很清楚:帮你跳过企业级开发里那60%重复的基础设施工作,让你专注业务本身。
下次写一个新项目,身份认证别手写,多租户别手写,审计日志别手写。刚子已经把ABP怎么发车、怎么搭路、最核心的两个场景(Swagger→数据库映射、加Book实体走全流程)都演示完了。剩下的看文档,照着Roadmap走就行了。
如果你觉得这篇有用,点个赞、转给还在从头堆代码的兄弟。
我是刚子,一个还在写.NET的老程序员。咱们下篇见!
1618



被折叠的 条评论
为什么被折叠?



