2024-06-01 16:01:56
摘要:一、仓储
仓储模式是ABP框架数据访问层的核心抽象,它提供了一种统一的方式来访问数据源,无论底层使用何种数据库技术(EF Core、MongoDB等)。
接口抽象:框架定义了一系列通用的仓储接口,如 IRepositoryTEntity, TKey。你的领域层和应用层只依赖于这些接口,而不是具体的实现,这严格遵循了DDD的持久化无关原则。
默认实现:ABP为EF、MongoDB和Dapper提供了这些仓储接口的开箱即用的实现。这意味着对于大多数标准的CRUD操作,无需编写任何仓储实现代码。
自定义仓储:对于复杂的查询或特定操作,可以定义自定义的仓储接口(如 ICustomRepository),并在基础设施层(如EntityFrameworkCore项目)中实现它。ABP的依赖注入系统会自动将其注册到容器中。
类关系图
1. 仓储接口体系
ABP定义了一套完整的仓储接口体系,位于Volo.Abp.Domain.Repositories命名空间:
//IRepository.cs
public interface IRepository { }
public interface IRepositoryTEntity : IReadOnlyRepositoryTEntity, IBasicRepositoryTEntity
where TEntity : class, IEntity
{
TaskTEntity FindAsync([NotNull] ExpressionFuncTEntity, bool predicate, bool includeDetails = true, CancellationToken cancellationToken = default);
TaskTEntity GetAsync([NotNull] ExpressionFuncTEntity, bool predicate, bool includeDetails = true, CancellationToken cancellationToken = default);
Task DeleteAsync([NotNull] ExpressionFuncTEntity, bool predicate, bool autoSave =……
阅读全文
2024-05-25 11:56:40
摘要:ABP是一个面向DDD的项目框架,接下来的内容将学习如何利用ABP来落地DDD的项目,我们今天先来总结一下DDD的核心思想。
一、什么是领域驱动设计
1. 传统软件开发
业务梳理 == 软件设计 == 开发
初期-简单-迭代-复杂-冗杂-屎山代码-牵一发而动全身-重构系统-演进
示例:订单服务(查询订单、创建订单、订单评价、支付……)
项目流程:讨论需求==数据库建模==项目开发==迭代数据库的设计==上线
2. 领域驱动开发
根据领域知识一步步驱动软件设计的过程就是领域驱动设计(DDD,Domain-Driven Design)
领域驱动设计(DDD)是一种处理高度复杂领域的设计思想
设计思想:通过分离技术实现的复杂性,并围绕业务概念构建领域模型来控制业务的复杂性
项目流程:领域模型=数据库设计
3. 战略设计和战术设计
领域驱动设计包括战略设计和战术设计两部分:
战略设计:从业务视角出发=》业务领域模型=》边界=》通用语言的限界上下文
战术设计:从技术视角出发=》技术实现=》实体、聚合根、值对象、领域服务……
二、领域驱动设计的基础概念
1. 领域和子域
领域(业务问题域)具体指一种特定的范围或区域,就是用来确定范围的,范围就是边界
细分-限定-领域模型-代码实现
领域越大业务范围就越大
领域可以进一步划分为子领域(子域 更小的)
子域对应一个更小的范围
我们来看一张经典的图
给桃树建立领域知识的步骤:
确定研究对象
对研究对象进行细分
对子对象再次进行细分
细分到最小单元
再来看一个电商项目的领域划分的例子:
电商领域可以分成:商品子域、销售子域、订单子域、物流子域
物流子域又可以分成:拣货子域、发货子域、派送子域
领域建模的过程和方法其核心思想就是将问题域逐步分解
降低业务理解和系统实现的复杂度
2. 核心域、通用域和支撑域
核心域:产品核心业务功能
通用域:被多个子域使用的通用功能(认证、授权、日志)
支撑域:既不包含业务核心功能,也不包含通用功能
电商平台中:销售子域是核心域,物流子域是支撑销售业务的,所以它的支撑域
植物研究领域中,需要根据不同情况来划分核心域
如果是在果园:果实就是核心域。为了让果实更饱满,果农可能会裁剪一些枝和叶
如果是在公园:花就是核心域
3. 通用语言
通过团队交流达成共识的,能够简……
阅读全文
2024-05-11 11:49:34
摘要:ABP框架并不重新发明轮子去实现认证,而是完美集成并简化了上述ASP.NET Core的认证流程。
模块化封装:当你使用ABP的启动模板时,认证的配置通常已经在模块中预先配置好,你只需要在appsettings.json中提供必要的参数(如JWT的签发者、密钥等)。
依赖注入集成:ABP通过ICurrentUser提供了对当前登录用户ID (UserId) 和租户ID (TenantId) 的便捷访问。这个接口的背后实现正是基于HttpContext.User及其声明(Claims)。
多租户支持:ABP的认证系统天然支持多租户,可以正确处理不同租户下的用户登录和会话管理。
ABP的主要价值在于整合与简化,它让你在使用强大的ASP.NET Core认证机制的同时,享受到ABP模块化和约定优先开发模式带来的便捷。
要学习好ABP的认证授权模块,我们来看一下ASP.NET Core的认证授权。
一、ASP.NET Core认证授权
1. 基本流程
UseAuthentication + AddAuthentication
UseAuthorization + AddAuthorization(.net源码内置)
[Authorize] [AllowAnonymous]
未登陆—访问—登陆—访问—退出
2. 理解认证
认证就是鉴别是张三----解读请求携带的用户信息
信息位置:怎么传递的凭证?Cookie,JWT,Other
信息格式:凭证是什么格式,加密问题
信息有效性:token过期了、签名不对
认证后信息保存:保存到context.User里面
特殊情况处理:没登陆、没权限、没xxx,这些就是认证需要知道的,需要干的活儿
登陆是怎么配合的?HttpContext.SignInAsync完成用户信息的写入(如:Cookie)
3. 理解授权
授权:就是检测下用户到底有没有权限访问某个方法
认证和授权的关系?
没有直接关系,认证获取用户信息保存到context.User,授权去使用
授权的时候,会用Scheme去认证一下,还有异常处理
检测凭据:
标记特性[Authorize] [AllowAnonymous]—就做授权检测
ASP.NET Core提供了灵活且强大的授权策略模型,主要包括:
基于角色的授权 ([Authorize(Roles =……
阅读全文
2024-05-04 11:03:40
摘要:前面重点介绍了ABP.vNext的模块化,以及模块化带来的核心价值动态API,今天我们开看一下ABP DI的扩展。
一、ABP DI功能介绍
1. 组件自动注册
SkipAutoServiceRegistration
AddAssemblyOf
AddAssembly
public class BlogModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
SkipAutoServiceRegistration = true;
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAssemblyOfBlogModule();
}
}
2. 默认的注册
模块类注册为singleton
MVC控制器(继承Controller或AbpController)被注册为transient
MVC页面模型(继承PageModel或AbpPageModel)被注册为transient
MVC视图组件(继承ViewComponent或AbpViewComponent)被注册为transient
应用程序服务(实现IApplicationService接口或继承ApplicationService类)注册为transient
存储库(实现IRepository接口)注册为transient
域服务(实现IDomainService接口)注册为transient
3. 依赖接口
ITransientDependency 注册为transient生命周期
ISingletonDependency 注册为singleton生命周期
IScopedDependency 注册为scoped生命周期
4. 特性
DependencyAttribute:控制服务的注册行为和生命周期
ExposeServicesAttribute:控制服务以哪些类型注册到容器中
[ExposeServices(typeof(……
阅读全文
2024-04-27 10:54:32
摘要:前面我们介绍了Abp的模块化,号称能随意拆分,随意组装, 能各种复用,是真的超牛。
但是这样就可以了吗?虽然是可以任意组装了,比如A项目被拆分成A、B两个项目了。如何才能做的优雅,做的有意义?
ABP的答案是这样的: 最强CP——ADO(Auto API+Dynamic Client+Options)
模块化===能力复用
Auto API Controller:轻松组合到一个进程,也可以模块化独立部署,拆分分布式
Dynamic C# Client:服务之间的调用(跟本地调用一样),都不用改代码,就可以轻松替换成分布式调用
定制化需求:Options选项模式完成定制
一、Auto API Controllers
创建应用程序服务后, 通常需要创建API控制器以将此服务公开为 HTTP(REST)API端点
典型的API控制器除了将方法调用重定向到应用程序服务并使用[HttpGet],[HttpPost],[Route]等属性配置REST API之外什么都不做
瘦控制器:本身是可以不要的
ABP可以按照惯例自动将应用程序服务配置为API控制器
大多数时候不关心它的详细配置,但它可以完全被自定义,而且还可以做好复用
Auto-API-Controllers自动API控制器,可以不用写控制器Action了,就可以直接把应用服务暴露成WebAPI
1. 配置方法
服务标记成IRemoteService
配置AbpAspNetCoreMvcOptions
TypePredicate
ConventionalControllers.Create
以上就完成了Auto-API-Controller
2. 自定义HttpMethod
ABP在确定服务方法的HTTP Method时使用命名约定:
Get:如果方法名称以GetList,GetAll或Get开头
Put:如果方法名称以Put或Update开头
Delete:如果方法名称以Delete或Remove开头
Post:如果方法名称以Create,Add,Insert或Post开头
Patch:如果方法名称以Patch开头
其他情况,Post 为 默认方式
自定义HTTP Method,则可以使用标准ASP.NET Core的属性 ([HttpPost], [HttpGet], [HttpPut]..……
阅读全文
2024-04-20 12:36:10
摘要:在讲ABP的模块实现前,我们先来认识一下ABP。
一、初识ABP
1. ABP vNext是什么
ASP.NET Core的开源WEB应用程序框架——就是再封装一层,扩展了一系列的封装,完成了很多通用的。
ABP是用于创建现代Web应用程序的完整架构和强大的基础设施! 遵循最佳实践和约定,为你提供SOLID开发经验
https://www.abp.io/
https://github.com/abpframework/abp
2. 架构特点
应用程序模块化
领域驱动设计DDD
微服务架构
支持仓储,基于O/RM实现数据库无关性和MongoDB集成
可扩展及可替换
3. 基础设施
领域驱动设计
模块化设计
多租户
Dependency Injection
认证与授权
事件总线
数据访问
Auto API及动态代理
4. 其他组件
横切面关注
虚拟文件系统
数据过滤
本地化
异常处理
审计日志
二、开启ABP.vNext
1. 使用 ABP CLI 工具直接生成
超多内容,请自行查看。https://docs.abp.io/zh-Hans/abp/latest/CLI
也可以在 https://abp.io 直接生成
可以查看基础项目 BookStore,账号 admin,密码 1q2w3E*
自动化生成一次性生成了太多代码,不适合学习,接下来我们要研究一下手动集成
2. 手动集成控制台项目
手动创建一个.net core控制台项目,添加核心nuget包,Volo.Abp
创建一个HelloWorldService服务,使用瞬时生命周期
[Dependency(ServiceLifetime.Transient)]
public class HelloWorldService()
{
public void Run()
{
Console.WriteLine(Hello World);
}
}
ABP是模块化的,所以我们要创建一个模块类 AppModule
public class AppModule : AbpModule
{
public override void OnApplicationInitialization(ApplicationInitializationContext ……
阅读全文