不同的编程语言都有构建Web Application的框架,比如C#中的ASP.NET Core和ABP,Java中的Spring Boot和Spring Cloud,Python中的Django和Flask,Node.js中的Express和Koa2,Go中的Beego和Gin等。今天要介绍的主角是ABP框架,以前叫做ASP.NET Boilerplate,现在叫做ABP vNext,简称为ABP框架。ABP可以提供了构建现代Web Application的完整架构和强大的基础设施,遵循DDD最佳实践和约定。特别是完整的模块化系统,能够开发可重复使用的应用程序模块,这一点对于软件工程领域来说是非常重要的。总之,ABP是一个非常具有前瞻性的优秀框架。
一.ABP框架概述
在.NET领域中,通常使用ASP.NET Core来写后端的Web API,ABP对其进行了无缝增强。在群里讨论,用一位群友的话来说就是:ABP像变形金刚一样,可以在单体和微服务项目之间切换;领域驱动设计[DDD]可以用的很重,也可以用的轻。根据项目情况,如果初期项目并不复杂,可以使用单体架构,随着项目演化变的复杂了,也可以很容易的转换为微服务架构,而DDD是复杂业务拆分的理论依据。简单理解,微服务是从技术的视角来看拆分问题,而DDD是从业务视角来看拆分问题。从而解决项目的可维护和三高问题[高并发|高性能|高可用]。
1.ABP架构
(1)微服务兼容
核心框架和预构建模块在设计时就考虑了微服务架构,因为很容易的在单体和微服务架构间转换。
(2)模块化架构
提供了完整的模块化系统,能够开发可重复使用的应用程序模块。
(3)领域驱动设计
实现基于DDD的分层架构并构建可维护的代码库,帮助开发基于DDD模式和准则的应用程序。
(4)多租户/Saas
提供了开箱即用的多租户模块,对于构建SaaS应用非常的方便。
2.ABP基础设施
(1)认证与授权
集成了ASP.NET Core Identity和IdentityServer4丰富的身份验证和授权选项,提供可扩展且详细的权限系统。
(2)横切关注点
Don't Repeat Yourself,专注于业务代码,并让ABP按照约定自动执行。
(3)分布式事件总线
使用带有RabbitMQ集成的内置分布式事件总线,可以轻松发布和使用分布式事件。
(4)用户界面主题
对于前后端不分离的项目,可以参考。但是对于前后端分离的项目,不用参考。
(5)数据过滤
自动过滤来自数据库的查询,以轻松实现软删除和多租户等模式。
(6)Bootstrap Tag Helpers和动态表单
对于前后端不分离的项目,可以参考。但是对于前后端分离的项目,不用参考。
(7)审计日志
自动跟踪系统中的所有操作和数据更改。
(8)HTTP APIs和动态代理
自动将应用程序服务公开为REST的HTTP API,并与动态JavaScript和C#代理一起使用。
3.ABP启动模板
各种启动模板提供了完整配置的解决方案,可以实现快速启动开发:
4.ABP CLI
对ABP解决方案执行常见操作的命令行工具,安装和更新ABP CLI:
dotnet tool install -g Volo.Abp.Cli
dotnet tool update -g Volo.Abp.Cli
ABP CLI所有可用的命令列表:
help:展示ABP CLI的用法帮助信息
new:生成基于ABP的启动模板
update:自动更新的ABP解决方案ABP相关的NuGet和NPM包
clean:删除当前目录下所有的BIN和OBJ子目录
add-package:添加ABP包到项目
add-module:添加应用模块到解决方案
generate-proxy:生成客户端代理以使用HTTP API端点
remove-proxy:移除以前生成的客户端代理
switch-to-preview:切换到ABP框架的最新预览版本
switch-to-nightly:切换解决方案所有ABP相关包为夜间构建版本
switch-to-stable:切换解决方案所有ABP相关包为最新的稳定版本
translate:当源代码控制存储库中有多个JSON[本地化]
login:使用在abp.io的用户名和密码在计算机上认证
login-info:展示当前登录用户信息
logout:在计算机注销认证
install-libs:为MVC/Razor Pages和Blazor Server UI类型安装NPM包
二.ABP框架功能
(1)多个UI选项
Angular,MVC,Razor Pages,Blazor。
(2)多个数据库提供程序
EF Core,MongoDB,Dapper。其中,Dapper支持不完善,坑多,最好还是用EF Core。
(3)ABP CLI
# Create a new layered application
abp new Acme.BookStore
# Create a new layered application using MongoDB
abp new Acme.BookStore -d mongodb
# Add a new module to the solution
abp add-module Volo.Blogging
(4)模块化
ABP中使用模块化的方法很简单,就是继承自AbpModule即可:
[DependsOn(
typeof(AbpEntityFrameworkCoreModule), //Depending on a framework module
typeof(MyBusinessModule) //Depending on your own module
)]
public class MyAppModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
//Configure DI and other modules...
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
//Perform some application initialization logic...
}
}
(5)多租户
主要是将不同租户间的数据进行隔离,ABP支持单一数据库,或每个租户单独数据库或者混合方式。
(6)Bootstrap标签助手
使用ABP的tag helper来简化它并利用智能感知:
<abp-card>
<img abp-card-image="Top" src="~/images/my-dog.png" />
<abp-card-body>
<abp-card-title>Card title</abp-card-title>
<abp-card-text>
<p>
This is a sample card component built by ABP bootstrap
card tag helper. ABP has tag helper wrappers for most of
the bootstrap components.
</p>
</abp-card-text>
<a abp-button="Primary" href="javascript:void(0)" >Go somewhere →</a>
</abp-card-body>
</abp-card>
输出结果如下所示:(7)动态表单
动态表单和tag helpers可从作为模型的C#类创建完整的表单:
查看:
<abp-dynamic-form abp-model="@Model.PersonInput" submit-button="true" />
模型:
public class PersonModel
{
[HiddenInput]
public Guid Id { get; set; }
[Required]
[EmailAddress]
[StringLength(255)]
public string Email { get; set; }
[Required]
[StringLength(32)]
[DataType(DataType.Password)]
public string Password { get; set; }
[StringLength(255)]
public string Address { get; set; }
public Gender Gender { get; set; }
}
结果:(8)认证与授权
主要是对ASP.NET Core Identity和IdentityServer4的继承,基本上满足身份验证和授权,并且很容易扩展权限系统。
(9)横切关注点
提供了授权、验证、缓存、异常处理、数据库连接和事务管理、审计日志、关联ID跟踪等常见的东西,可专注于业务代码,并让ABP按照约定自动执行即可。
(10)Bundling & Minification
ABP提供了一个简单、动态、功能强大、模块化的内置Bundling&Minification系统。
<abp-style-bundle name="MyGlobalBundle">
<abp-style src="/libs/bootstrap/css/bootstrap.css" />
<abp-style src="/libs/font-awesome/css/font-awesome.css" />
<abp-style src="/libs/toastr/toastr.css" />
<abp-style src="/styles/my-global-style.css" />
</abp-style-bundle>
(11)虚拟文件系统
虚拟文件系统使管理文件系统[磁盘]上不存在的文件成为可能,它主要用于将[js|css|image|cshtml...]文件嵌入到程序集中,并在运行时像物理文件一样使用它们。
(12)主题
主题系统允许通过基于最新的Bootstrap框架定义一组通用基础库和布局来独立开发应用程序和模块主题。
(13)后台作业
定义简单的类以在队列中在后台执行作业,使用内置的作业管理器或集成自己的作业管理器。Hangfire&RabbitMQ集成已经可用:
public class EmailSendingJob : BackgroundJob<EmailSendingArgs>
{
private readonly IEmailSender _emailSender;
public EmailSendingJob(IEmailSender emailSender)
{
_emailSender = emailSender;
}
public override void Execute(EmailSendingArgs args)
{
_emailSender.Send(
args.EmailAddress,
args.Subject,
args.Body
);
}
}
(14)DDD基础设施
基于域驱动设计模式和准则构建分层应用程序的完整基础设施,包括聚合根、实体、值对象、领域服务、仓储、应用程序服务、数据传输对象、规范等:
public class BookAppService : ApplicationService, IBookAppService
{
private readonly IRepository<Book, Guid> _bookRepository;
public BookAppService(IRepository<Book, Guid> bookRepository)
{
_bookRepository = bookRepository;
}
public async Task CreateAsync(CreateBookDto input)
{
var book = new Book(
GuidGenerator.Create(),
input.Name,
input.Type,
input.Price
);
await _bookRepository.InsertAsync(book);
}
}
(15)自动REST APIs
ABP可以按照约定自动将应用程序服务配置为API控制器:(16)动态客户端代理
从JavaScript和C#客户端轻松使用API:
//Call remote APIs just like local functions in JavaScript
acme.bookStore.book
.getList({})
.done(function (result) {
//...
});
(17)分布式事件总线
使用带有RabbitMQ集成的内置分布式事件总线,可以轻松发布和使用分布式事件:
发布事件:
public class PublisherDemo : ITransientDependency
{
private readonly IDistributedEventBus _distributedEventBus;
public PublisherDemo(
IDistributedEventBus distributedEventBus)
{
_distributedEventBus = distributedEventBus;
}
public async Task RunAsync()
{
//Publish an event
await _distributedEventBus.PublishAsync(
new StockCountChangedEvent(productId, 42)
);
}
}
处理事件:
public class MyEventHandler
: IDistributedEventHandler<StockCountChangedEvent>
{
public Task HandleEventAsync(StockCountChangedEvent eventData)
{
//Handle the event and execute your business
}
}
(18)BLOB存储
BLOB存储系统提供了BLOB的抽象,ABP提供了一些预构建的存储提供程序集成[Azure|AWS|文件系统|数据库等],可以轻松的在应用程序中使用它们:
public class MyService : ITransientDependency
{
private readonly IBlobContainer _blobContainer;
public MyService(IBlobContainer blobContainer)
{
_blobContainer = blobContainer;
}
public async Task SaveBytesAsync(byte[] bytes)
{
await _blobContainer.SaveAsync("my-blob", bytes);
}
public async Task<byte[]> GetBytesAsync()
{
return await _blobContainer.GetAllBytesOrNullAsync("my-blob");
}
}
(19)文本模板
文本模板是基于模板和模型[数据对象]使用动态渲染内容。比如可以使用预构建的模板来创建动态的电子邮件内容:
var result = await _templateRenderer.RenderAsync(
"PasswordReset", //the template name
new PasswordResetModel
{
Name = "john",
Link = "https://abp.io/example-link?userId=123&token=ABC"
}
);
(20)测试基础设施
框架已经考虑了单元和集成测试,提供基类使其更容易。启动模板已预先配置用于测试:
public class MyService_Tests : AbpIntegratedTest<MyModule>
{
private readonly MyService _myService;
public MyService_Tests()
{
_myService = GetRequiredService<MyService>();
}
[Fact]
public async Task MyService_Should_Do_It()
{
//Act
var result = _myService.DoIt();
//Assert
result.ShouldBe(42);
}
}
(21)审计日志
针对关键业务应用程序的内置审计日志记录,请求、服务、方法级别的审计日志记录以及具有属性级别详细信息的实体历史记录。
(22)对象映射
对象到对象映射抽象AutoMapper集成:
public class PersonService
{
//Inject IObjectMapper
private readonly IObjectMapper _objectMapper;
public PersonService(IObjectMapper objectMapper)
{
_objectMapper = objectMapper;
}
public PersonDto GetPerson(Guid id)
{
Person person = GetPersonEntityFromRepository(id);
//Use for Entity to DTO mapping
return _objectMapper.Map<Person, PersonDto>(person);
}
}
(23)电子邮件和短信抽象
IEmailSender和ISmsSender抽象使应用程序逻辑与基础设施解耦。先进的电子邮件模板系统允许创建和本地化电子邮件模板,并在需要时轻松使用:
public async Task SendWelcomeEmailAsync(string emailAddress, string name)
{
//Get the email template
var template = await _emailTemplateProvider.GetAsync("WelcomeEmailTemplate");
//Replace placeholders
template.Replace("name", name);
//Send email
await _emailSender.SendAsync(
emailAddress,
"Welcome to our application!",
template.Content
);
}
(24)本土化
本地化系统允许在纯JSON文件中创建资源,并使用它们来本地化UI。它支持继承、扩展和JavaScript集成等高级方案,同时与AspNetCore的本地化系统完全兼容:
{
"culture": "en",
"texts": {
"WelcomeMessage": "Welcome to the application!",
"HelloWorld": "Hello World"
}
}
(25)设置管理
定义应用程序的设置,并根据当前配置,租户和用户在运行时获取值。
(26)扩展方法
标准类型的扩展方法和助手使代码更加清晰和易于编写:
//Convert a string to camelCase
"HelloWorld".ToCamelCase(); //returns "helloWorld"
//Truncate a string with "..." postfix
"This is a test string".TruncateWithPostfix(12); //returns "This is a..."
//Convert a string to int
"42".To<int>(); //returns 42 as int
//Check if a value occurs in a list
5.IsIn(1, 3, 5, 7); //returns true
//Check if a value is between a range
5.IsBetween(6, 12); //returns false
(27)面向切面的编程
提供合适的基础设施来创建动态代理并实现面向切面的编程,拦截任何类,并在每次方法执行之前和之后执行代码:
//Inherit from the AbpInterceptor to log all method executions
public class MyLoggingInterceptor : AbpInterceptor, ITransientDependency
{
private readonly ILogger<MyLoggingInterceptor> _logger;
public MyLoggingInterceptor(ILogger<MyLoggingInterceptor> logger)
{
_logger = logger;
}
public async override Task InterceptAsync(IAbpMethodInvocation invocation)
{
LogInvocation(invocation);
await invocation.ProceedAsync();
}
private void LogInvocation(IAbpMethodInvocation invocation)
{
/* Access to all the information about the method execution
* including method, class and provided arguments */
_logger.LogInformation(
"Executing the method: " +
invocation.Method.Name +
" of class " +
invocation.TargetObject.GetType().FullName
);
}
}
(28)依赖注入
无需手动注册类以进行依赖项注入,按照约定自动注册常用服务类型。对于其它类型的服务,可以使用接口和属性来使其变得更方便:
/* Automatically registers MyService as transient.
* Then you can inject by IMyService or MyService.
*/
public class MyService : IMyService, ITransientDependency
{
}
(29)数据过滤
定义和使用数据过滤器,这些过滤器在从数据库中查询实体时会自动应用。当实现简单的接口时,可立即使用软删除功能和多租户过滤器:
public class MyEntity : Entity<Guid>, ISoftDelete
{
public bool IsDeleted { get; set; }
}
三.ABP项目工程
只是介绍3种项目类型的结果,具体代码另写一篇文章介绍:
1.项目类型-应用程序[分层]
![cf11791582eec6c868cc1390e308e0ac.png](https://i-blog.csdnimg.cn/blog_migrate/8ed283e6ff67b7360ad1cb84b37f0165.png)
2.项目类型-应用程序[单层]
以前是没有单层项目的,可能大家在构建中小型Web Application时发现使用分层的应用程序还是太重量级了,官方后来就添加了单层项目:
3.项目类型-模块
查了下ABP官网,推测AbpModule.Web.Unified项目是AbpModule.HttpApi.Host和AbpModule.Web.Host的结合体:
四.ABP项目资料
1.ABP官方文档
由于ABP发展速度,因此资料很少,网上找的资料基本上过时了。ABP官方文档应该是最新的、最全的学习资料了:
2.ABP GitHub
通过ABP GitHub可以研究框架模块和应用程序模块的具体实现原理。框架模块:这些是框架的核心模块,像缓存、邮件、主题、安全性、序列化、验证、Ef Core集成、MongoDB集成等等,它们没有应用程序/业务功能,但通过提供通用基础架构,集成和抽象会使日常开发更加容易。应用程序模块:这些模块是实现特定的应用程序/业务功能,像博客、文档管理、身份管理、租户管理等等,它是通常有自己的实体、服务、API和UI组件。开源的应用程序模块如下所示:(1)Audit Logging:用于将审计日志持久化到数据库
(2)Background Jobs:用于在使用默认后台作业管理器时保存后台作业
(3)Blogging:用于创建精美的博客,ABP的博客就使用了此模块
(4)Docs:用于创建技术文档页面,ABP的文档就使用了此模块
(5)Feature Management:用于保存和管理功能
(6)Identity:基于Microsoft Identity管理组织单元、角色、用户和它们的权限
(7)Identity Server:集成了IdentityServer4
(8)Permission Management:用于保存权限
(9)Setting Management:用于保存设置
(10)Tenant Management:管理多租户应用程序的租户
(11)Users:抽象用户,因此其它模块可以依赖此模块而不是Identity模块
(12)Virtual File Explorer:提供简单的UI查看虚拟文件系统中的文件
3.EasyAbp GitHub
尤其值得一提的是AbpHelper.GUI和 AbpHelper.CLI这2个项目,相当于是ABP Suite。作为低代码工具,如果使用得当可以提交开发效率。另外要介绍的是awesome-abp仓储,这里面应该是目前最全的ABP学习资料了:
4.ABP书籍
目前(1)既有英文版还有中文版,但是(2)只有英文版。下载方式详见文档底部:
(1)《Implementing Domain Driven Design》
(2)《Mastering ABP Framework》
五.ABP商业版本
ABP商业版预建应用程序模块、高级启动模板、快速应用程序开发工具、专业UI主题和高级支持等。其中,预建应用程序模块包括Account、Audit Logging、Identity、Identity Server UI、Language Management、SaaS、Lepton Theme、Payment、Text Template Management、Chat、File Management、CMS Kit、Forms、GDPR、Twilio SMS、Blogging、Docs等。初次之外,值得一提的是ABP Suite,相当于是一个低代码工具,可以加速CRUD开发。
1.首页
![869b7f61878ab6753d4d8aff1636558f.png](https://i-blog.csdnimg.cn/blog_migrate/2fb03188917b1b661108f50cfa5954ef.png)
2.仪表板
![f9998d18d6dcafd376c5f53eff131f06.png](https://i-blog.csdnimg.cn/blog_migrate/bfe24c26ecb01e861186ac1e69b61765.png)
3.文件管理
![b388fdded04952fe9efd1949d9969f58.png](https://i-blog.csdnimg.cn/blog_migrate/0defac243a14a92f9422694e781edfa6.png)
4.SaaS
4.1租户
![331c314bcef9567a42297d03ef811c45.png](https://i-blog.csdnimg.cn/blog_migrate/c952096bcc3b5b257bc603bd07cebc09.png)
4.2版本
![2a4c7d5ffc692fa1d533aa06c13c955b.png](https://i-blog.csdnimg.cn/blog_migrate/d5ae4167bb3b3f47349a2e0ef9b46d92.png)
5.管理
5.1身份标识管理
(1)组织机构(2)角色
(3)用户
(4)声明类型
(5)安全日志
5.2Identity Server
(1)客户端(2)Identity资源
(3)Api资源
(4)Api Scope
5.3语言管理
(1)语言[官网打不开]
(2)语言文本[官网打不开]
5.4文本模板
![cc856a2e5f3eb00bc6fca3d46d22263f.png](https://i-blog.csdnimg.cn/blog_migrate/18215d18a1d227128d982b1a2e0eb3f0.png)
5.5审计日志
![33342b1c51d68e5fd0343dc09c5e5ede.png](https://i-blog.csdnimg.cn/blog_migrate/6458ad0c6caa73c0167311c1b3f255b3.png)
5.6设置
(1)身份标识管理(2)Lepton主题
(3)账户-通用
(4)账户-双因素
(5)账户-验证码
除了ABP官方商业版外,还有非官方的商业版,比如52ABP,感兴趣可以了解下。
资料下载区
1.Implementing Domain Driven Design:公众号后台回复:2
2.基于ABP Framework实现领域驱动设计:公众号后台回复:3
3.Mastering ABP Framework:公众号后台回复:4
或者
1.Implementing Domain Driven Design: https://url39.ctfile.com/f/2501739-610635606-674948?p=2096(访问密码:2096)
2.基于ABP Framework实现领域驱动设计: https://url39.ctfile.com/f/2501739-610635608-94e753?p=2096(访问密码:2096)
3.Mastering ABP Framework: https://url39.ctfile.com/f/2501739-610635610-9a8f66?p=2096(访问密码:2096)
参考文献:
[1]ABP官方网站:https://abp.io/
[2]Mastering ABP Framework:https://abp.io/books/mastering-abp-framework
[3]实现领域驱动设计:https://abp.io/books/implementing-domain-driven-design
[4]ABP文档:https://docs.abp.io/zh-Hans/abp/latest/
[5]ABP社区:https://community.abp.io/
[6]ABP Commercial Documentation:https://docs.abp.io/en/commercial/latest
人工智能干货推荐专注于人工智能领域的技术分享
游戏元宇宙专注于游戏领域的技术分享