ABP vnext模块化架构的最佳实践的实现

在上一篇文章《手把手教你用Abp vnext构建API接口服务》中,我们用ABP vnext实现了WebAPI接口服务,但是并非ABP模块化架构的最佳实践。我本身也在学习ABP,我认为ABP新手应该从最佳实践开始学习,可以少走很多弯路,所以写了这篇最佳实践来做个总结,同时给其他朋友们提供一点参考。

一、什么是模块化架构的最佳实践

ABP是一个包含许多nuget包的模块化框架。它提供了一个完整的基础架构来开发你自己的具有实体、服务、数据库集成、API、 UI组件等等功能的应用程序模块。
模块化架构的最佳实践就是按功能的划分创建相应的模块实现的服务,必要时可以把模块发布到nuget,由其他模块安装组合成新的服务或单体应用。这样就可以复用现有的模块功能,快速的交付产品,告别996。

二、模块化架构的最佳实践说明

这部分内容全部来自于模块化架构最佳实践 & 约定,有兴趣的朋友可以去官方文档查看。如果已经很熟悉ABP分层了,可以直接阅读第三部分。

1、解决方案结构:
  1. 为每个模块创建一个单独的解决方案。将解决方案命名为CompanyName.ModuleName。

  2. 一个模块做为分层项目开发,因为它有几个包(项目)是相互关联的。每个包都有自己的模块定义文件,并显式声明所依赖的包/模块的依赖关系。

2、模块分层和包之间的关系
下面展示了一个分层良好的模块中的包以及它们之间的依赖关系:

领域层

将领域层划分为两个项目:

  1. Domain.Shared 包(项目) 命名为CompanyName.ModuleName.Domain.Shared,包含常量,枚举和其他类型,它不能包含实体、存储库、域服务或任何其他业务对象。可以安全地与模块中的所有层使用。此包也可以与第三方客户端使用。

  2. Domain 包(项目) 命名为CompanyName.ModuleName.Domain,包含实体、仓储接口、领域服务接口及其实现和其他领域对象。Domain 包依赖于 Domain.Shared 包。

应用服务层

将应用服务层划分为两个项目:

  1. Application.Contracts 包(项目) 命名为CompanyName.ModuleName.Application.Contracts,包含应用服务接口和相关的数据传输对象(DTO)。Application contract 包依赖于 Domain.Shared 包。

  2. Application 包(项目)命名为CompanyName.ModuleName.Application,包含应用服务实现。Application 包依赖于 Domain 包和 Application.Contracts 包。

基础设施层
  1. 为每个orm/数据库集成创建一个独立的集成包,比如Entity Framework Core 和 MongoDB。例如,创建一个抽象Entity Framework Core集成的CompanyName.ModuleName.EntityFrameworkCore 包。ORM 集成包依赖于 Domain 包。不推荐依赖于orm/数据库集成包中的其他层.

  2. 为每个主要的库创建一个独立的集成包, 在不影响其他包的情况下可以被另一个库替换.

HTTP 层
  1. 创建命名为CompanyName.ModuleName.HttpApi的HTTP API包,为模块开发REST风格的HTTP API。

  • HTTP API 包只依赖于 Application.Contracts 包。不要依赖 Application 包。

  • 为每个应用服务创建一个Controller (通常通过实现其接口)。这些控制器使用应用服务接口来委托操作。它根据需要配置路由,HTTP方法和其他与Web相关的东西。

  • 创建一个为HTTP API包提供客户端服务的HTTP API Client包,它的命名为Companyname.ModuleName.HttpApi.Client。这些客户端服务将应用服务接口实现远程端点的客户端。

    • HTTP API Client包仅依赖于 Application.Contracts包。

    • 推荐使用ABP框架提供的动态代理HTTP C#客户端的功能。

    Web 层

    创建命名为CompanyName.ModuleName.Web的Web包。包含页面、视图、脚本、样式、图像和其他UI组件。Web包仅依赖于HttpApi包。

    三、实现模块化架构的最佳实践

    开发环境:Mac Visual Studio Code
    SDK:dotnet core 3.1
    数据库:PostgreSQL

    创建项目文件夹,然后进入改文件夹的命令目录执行以下命令创建项目

    在上一篇文章中引入的是Volo.Abp.Identity的包,现在改用Volo.Abp.DDD的包,更简洁。

    /**创建解决方案**/
    dotnet new sln
    /**创建模块分层**/
    dotnet new classlib -o src/Lemon.Account.Domain.Shared
    dotnet new classlib -o src/Lemon.Account.Domain
    dotnet new classlib -o src/Lemon.Account.EntityFrameworkCore
    dotnet new classlib -o src/Lemon.Account.EntityFrameworkCore.DbMigrations
    dotnet new classlib -o src/Lemon.Account.Application.Contracts
    dotnet new classlib -o src/Lemon.Account.Application
    dotnet new classlib -o src/Lemon.Account.HttpApi
    dotnet new classlib -o src/Lemon.Account.HttpApi.Client
    dotnet new web -o src/Lemon.Account.Host/**加入解决方案**/
    dotnet sln Lemon.Account.sln add src/Lemon.Account.Domain.Shared
    dotnet sln Lemon.Account.sln add src/Lemon.Account.Domain
    dotnet sln Lemon.Account.sln add src/Lemon.Account.EntityFrameworkCore
    dotnet sln Lemon.Account.sln add src/Lemon.Account.EntityFrameworkCore.DbMigrations
    dotnet sln Lemon.Account.sln add src/Lemon.Account.Application.Contracts
    dotnet sln Lemon.Account.sln add src/Lemon.Account.Application
    dotnet sln Lemon.Account.sln add src/Lemon.Account.HttpApi
    dotnet sln Lemon.Account.sln add src/Lemon.Account.HttpApi.Client
    dotnet sln Lemon.Account.sln add src/Lemon.Account.Host/**分层间互相引用**/
    dotnet add src/Lemon.Account.Domain/Lemon.Account.Domain.csproj reference src/Lemon.Account.Domain.Shared/Lemon.Account.Domain.Shared.csproj
    dotnet add src/Lemon.Account.EntityFrameworkCore/Lemon.Account.EntityFrameworkCore.csproj reference src/Lemon.Account.Domain/Lemon.Account.Domain.csproj
    dotnet add src/Lemon.Account.EntityFrameworkCore.DbMigrations/Lemon.Account.EntityFrameworkCore.DbMigrations.csproj reference src/Lemon.Account.EntityFrameworkCore/Lemon.Account.EntityFrameworkCore.csproj
    dotnet add src/Lemon.Account.Application/Lemon.Account.Application.csproj reference src/Lemon.Account.Application.Contracts/Lemon.Account.Application.Contracts.csproj
    dotnet add src/Lemon.Account.Application/Lemon.Account.Application.csproj reference src/Lemon.Account.Domain/Lemon.Account.Domain.csproj
    dotnet add src/Lemon.Account.HttpApi/Lemon.Account.HttpApi.csproj reference src/Lemon.Account.Application.Contracts/Lemon.Account.Application.Contracts.csproj
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj reference src/Lemon.Account.EntityFrameworkCore.DbMigrations/Lemon.Account.EntityFrameworkCore.DbMigrations.csproj
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj reference src/Lemon.Account.Application/Lemon.Account.Application.csproj
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj reference src/Lemon.Account.HttpApi/Lemon.Account.HttpApi.csproj/**添加nuget依赖包**/
    dotnet add src/Lemon.Account.Domain.Shared/Lemon.Account.Domain.Shared.csproj package Volo.Abp.Validation
    dotnet add src/Lemon.Account.Domain/Lemon.Account.Domain.csproj package Volo.Abp.Ddd.Domain
    dotnet add src/Lemon.Account.Domain/Lemon.Account.Domain.csproj package Lemon.Commondotnet add src/Lemon.Account.EntityFrameworkCore/Lemon.Account.EntityFrameworkCore.csproj package Volo.Abp.EntityFrameworkCore
    dotnet add src/Lemon.Account.EntityFrameworkCore/Lemon.Account.EntityFrameworkCore.csproj package Volo.Abp.EntityFrameworkCore.PostgreSqldotnet add src/Lemon.Account.EntityFrameworkCore.DbMigrations/Lemon.Account.EntityFrameworkCore.DbMigrations.csproj package Volo.Abp.EntityFrameworkCore
    dotnet add src/Lemon.Account.EntityFrameworkCore.DbMigrations/Lemon.Account.EntityFrameworkCore.DbMigrations.csproj package Volo.Abp.EntityFrameworkCore.PostgreSql
    dotnet add src/Lemon.Account.EntityFrameworkCore.DbMigrations/Lemon.Account.EntityFrameworkCore.DbMigrations.csproj package Microsoft.EntityFrameworkCore.Designdotnet add src/Lemon.Account.Application.Contracts/Lemon.Account.Application.Contracts.csproj package IdentityModel
    dotnet add src/Lemon.Account.Application.Contracts/Lemon.Account.Application.Contracts.csproj package Volo.Abp.Ddd.Application.Contractsdotnet add src/Lemon.Account.Application/Lemon.Account.Application.csproj package Volo.Abp.Ddd.Application
    dotnet add src/Lemon.Account.Application/Lemon.Account.Application.csproj package Volo.Abp.AutoMapperdotnet add src/Lemon.Account.HttpApi/Lemon.Account.HttpApi.csproj package Volo.Abp.AspNetCore.Mvcdotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Volo.Abp.AspNetCore.Mvc
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Swashbuckle.AspNetCore
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Microsoft.AspNetCore.DataProtection.StackExchangeRedis
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Microsoft.Extensions.Caching.StackExchangeRedis
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Serilog.AspNetCore
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Serilog.Settings.Configuration
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Serilog.Sinks.Async
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Serilog.Sinks.File
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Volo.Abp.AspNetCore.Serilog
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package Volo.Abp.Autofac
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj package IdentityServer4.AccessTokenValidation
    dotnet add src/Lemon.Account.Host/Lemon.Account.Host.csproj reference src/Lemon.Account.EntityFrameworkCore.DbMigrations/Lemon.Account.EntityFrameworkCore.DbMigrations.csproj
    实现领域层

    在Domain创建实体类及其约束关联,具体代码请看UserData类,此处不再详细说明。

    实现基础设施层

    在EntityFrameworkCore创建AccountDbContext类和LemonAccountDbContextModelCreatingExtensions类。请特别关注LemonAccountDbContextModelCreatingExtensions类,主要是用来定义实体在数据库表中的字段属性。

    实现应用服务层
    实现httpapi
    用swagger调试接口

    进入Host目录,执行命令

    dotnet watch run


    服务启动成功,在浏览器打开链接http://localhost:5000/swagger/index.html,开始调试账号注册和验证接口。结果如下:



    四、模块化架构的最佳实践的好处

    使用模块化架构的好处有几点:

    1. 可以方便的更换模块
      比如我现在用的数据库是PostgreSQL,如果想要更换成MySQL,只要以EntityFrameworkCore层为基础,新增一个MySQL连接库,就可以在不改变业务逻辑的前提下快速的切换数据库。

    dotnet new classlib -o src/Lemon.Account.EntityFrameworkCore.MySQL
    dotnet new classlib -o src/Lemon.Account.EntityFrameworkCore.MySQL.DbMigrations
    dotnet sln Lemon.Account.sln add src/Lemon.Account.EntityFrameworkCore.MySQL
    dotnet sln Lemon.Account.sln add src/Lemon.Account.EntityFrameworkCore.MySQL.DbMigrationsdotnet add src/Lemon.Account.EntityFrameworkCore.MySQL/Lemon.Account.EntityFrameworkCore.MySQL.csproj reference src/Lemon.Account.Domain/Lemon.Account.Domain.csproj
    dotnet add src/Lemon.Account.EntityFrameworkCore.MySQL.DbMigrations/Lemon.Account.EntityFrameworkCore.MySQL.DbMigrations.csproj reference src/Lemon.Account.EntityFrameworkCore.MySQL/Lemon.Account.EntityFrameworkCore.MySQL.csprojdotnet add src/Lemon.Account.EntityFrameworkCore.MySQL/Lemon.Account.EntityFrameworkCore.MySQL.csproj package Volo.Abp.EntityFrameworkCore.MySQLdotnet add src/Lemon.Account.EntityFrameworkCore.MySQL.DbMigrations/Lemon.Account.EntityFrameworkCore.MySQL.DbMigrations.csproj package Microsoft.EntityFrameworkCore.Design
    

    最后再修改ConnectionStrings default为mysql的连接,修改LemonAccountHostModule的依赖项LemonAccountEntityFrameworkCoreDbMigrationsModule为MySQL

    1. 单体应用和微服务无缝切换
      模块开发完成后,一般当作微服务来部署;或者把模块发布到nuget,在单体应用的各个分层中引入模块,多个模块在单体应用中的应用就构成了一个完整系统服务。

    2. 模块复用
      由于模块是发布到nuget的,所以如果有新的项目需要用到相同功能的,可以直接从nuget引入安装,无需重复开发或者复制代码。

    3. 自动API控制器

    4. 动态 C# API 客户端

    GiHub地址:https://github.com/huangbenq/abp-samples

    参考文档:

    1. 模块化:https://docs.abp.io/zh-Hans/abp/latest/Module-Development-Basics

    2. 最佳实践:https://docs.abp.io/zh-Hans/abp/latest/Best-Practices/Index

    3. 自动API控制器:https://docs.abp.io/zh-Hans/abp/latest/API/Auto-API-Controllers

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/305684.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iphone查看删除的短信_手机资讯:iPhone手机可以批量删除短信吗如何操作

如今使用IT数码设备的小伙伴们是越来越多了,那么IT数码设备当中是有很多知识的,这些知识很多小伙伴一般都是不知道的,就好比最近就有很多小伙伴们想要知道iPhone手机可以批量删除短信吗如何操作,那么既然现在大家对于iPhone手机可…

如何在 C# 8 中使用 模式匹配

模式匹配 是在 C# 7 中引入的一个非常????的特性,你可以在任何类型上使用 模式匹配,甚至是自定义类型,而且在 C# 8 中得到了增强,引入了大量的新模式类型,这篇文章就来讨论如何在 C# 8 中使用模式匹配。C# 8 中的表…

Hadoop 中zoo_0基础如何入门HADOOP

原标题:0基础如何入门HADOOP学习一样东西,肯定先要了解这个东西是什么,那什么是HADOOP呢?我们就来看看什么是HADOOP和如何学习HADOOP及学习内容。一,什么是HADOOPHADOOP是apache旗下的一套开源软件平台HADOOP提供的功能…

.NET 5 程序高级调试-WinDbg

上周和大家分享了.NET 5开源工作流框架elsa,程序跑起来后,想看一下后台线程的执行情况。抓了个进程Dump后,使用WinDbg调试,加载SOS调试器扩展,结果无法正常使用了:0:000> .loadby sos clrUnable to find…

.Net在线编辑工具.NET Fiddle

介绍推荐工具:.NET Fiddle推荐理由:在线调试,编译,运行.net代码,同时支持C#,VB.NET,F#推荐说明::对于.NET开发者来说是福音,因为我们可以不用再担心环境与庞大…

Typora markdown公式换行等号对齐_下了31个markdown编辑器,我就不信选不出一个好用的...

markdown编辑器测评标准总体标准渲染领域编辑领域数据管理其他TyporaVnoteMwebJoplinZettlrmacdownulyssesMarktextghostwriterfocusedbywordmarkedFarBoxNotablebear(熊掌笔记)iA writerMarxico(马克飞象)JetBrains系列的IDEsublime(贫穷,没有插件&…

WSUS专题之二:部署与规划1

部署场景: 我们这里仅讨论和Internet完全物理隔离的企业内网的WSUS部署 Internet断开的WSUS服务器环境 部署WSUS服务时,并不要求你必须连接到Internet。对于没有连接到Internet的网络环境,你一样可以部署WSUS服务。通过在其他连接到Internet上的WSUS服务…

.Net Core in Docker - 使用阿里云Codepipeline及阿里云容器镜像服务实现持续交付/部署(CD)...

上一次演示了如何.Net Core in Docker - 使用阿里云Codepipeline及阿里云容器镜像服务实现持续集成(CI),讲到这里我们push一下代码后就自动编译、自动跑单元测试、自动构建镜像、自动推送镜像到私仓。那么离我们最初设定的目标只差那么一小步…

spyder pyecharts不显示_我的显示器需要定时校色吗?

在对图像色彩有要求的领域中,显示器的色彩准确是相当重要的。专业的显示器,能够具有更大的色域,更大的色深,以及更精确的ΔE色准值。这也是一个专业显示器所应有的品质。但是,我们在讨论色彩准确性的同时,往…

外观模式(Façade Pattern)

概述 在软件开发系统中,客户程序经常会与复杂系统的内部子系统之间产生耦合,而导致客户程序随着子系统的变化而变化。那么如何简化客户程序与子系统之间的交互接口?如何将复杂系统的内部子系统与客户程序之间的依赖解耦?这就是要说…

WTM5.0发布,全面支持.net5

点击上方蓝字关注我们WTM5.0全面支持.net5WTM5.0是WTM框架开源2年以来最大的一次升级,全面支持.net5,大幅重构了底层代码,针对广大用户提出的封装过度,不够灵活,性能不高等问题进行了彻底的修改。这次升级使WTM继续保持…

rsa 模数 指数转换 c语言_模数转换,你必须知道的8个经典ADC转换电路方案

模数转换器即A/D转换器,或简称ADC,通常是指一个将模拟信号转变为数字信号的电子元件。通常的模数转换器是将一个输入电压信号转换为一个输出的数字信号。由于数字信号本身不具有实际意义,仅仅表示一个相对大小。故任何一个模数转换器都需要一…

linux定时关机命令_win10电脑定时关机命令

电脑定时关机命令可以帮助用户们很好的去设置电脑自动关机等,自己无需操作,电脑也会在对应的时间自动关机,使用起来还是非常方便的,现在就来看看电脑定时关机命令教程吧~电脑定时关机命令是什么:一、CMD设置关机1、点击…

为你的项目启用可空引用类型

为你的项目启用可空引用类型IntroC# 从 8.0 开始引入了可空引用类型,我们可以为项目启用可空引用类型来借助编译器来帮助我们更好的处理代码中的空引用的处理,可以避免我们写很多不必要 null 检查,提高我们的效率Why为什么我们要启用可空引用…

有哪些编辑软件可以编辑c语言,可以推荐一个手机上最好用且免费的c语言编辑器吗?...

C4droid(又名C编译器)呗,一个既可以编辑,还可以运行C语言的手机编程软件,下面我简单介绍一下这个软件的安装和使用:1.首先,安装C4droid,这个直接在手机应用中搜索就行,如下,大概也就…

cas 4.2.7 官方手册_海城市地区,保险手册核验的简单流程

最近海城市社保正在进行保险手册的核验工作,据说是要将当地社保数据并网,由省社保机构监督管理。我们这个百万人口的县级市,核验工作只由一个部门在固定的办事大厅里完成,工作量也是相当大了。核验工作自9月末开始,已进…

在 C# 中生成代码的四种方式——包括.NET 5中的Source Generators

Microsoft在最新的C#版本中引入了Source Generator。这是一项新功能,可以让我们在代码编译时生成源代码。在本文中,我将介绍四种C#中的代码生成方式,以简化我们的日常工作。然后,您可以视情况选择正确的方法。在 .NET 中&#xff…

powercfg -h off_驭鲛记的主演会是谁?肖战关系特别好的艺人朋友呢?白敬亭和吴映洁有没有故事啊?高伟光是不是隐婚生子了?讲讲管h和马司令呗?...

近期后台提问的比较多,没被翻牌的小可爱们不要着急,我会尽力把大家的问题都照顾到,笔芯1. 扒扒,想知道华策驭鲛记的主演会是谁?主演还没定,女主在接触热巴,男主还没接触,这个戏明年才…

使用 C# 9 的records作为强类型ID - JSON序列化

使用 C# 9 的records作为强类型ID - 路由和查询参数在本系列的上一篇文章中使用 C# 9 的records作为强类型ID - 路由和查询参数,我们注意到强类型ID的实体,序列化为 JSON 的时候报错了,就像这样:{"id": {"value&qu…

HP LaserJet 1010卡纸解决方法

HP LaserJet 1010 系列打印机在打印过程中出现卡纸多由以下原因造成:1、纸盒里放入了过多的纸张或纸张位置没有放好。2、打印时使用的介质类型超出打印机的支持范围。常见卡纸位置:1 、硒鼓下方;2 、进纸口;3 、出纸口图 2&#x…