@

假设有一个按照官方sample搭建的微服务项目,并安装好了abp-cli。

需要创建一个名为GDMK.CAH.Common的模块,并在模块中创建标签管理功能

因为大部分的代码是自动生成的,此示例仅描述需要手动更改的内容。我们以创建一个全新的最小化的微服务模块为例,需要做以下几步:

创建模块

用abp-cli创建一个新的模块

在项目根目录下执行以下命令:

abp new GDMK.CAH.Common --template module --no-ui --ui='none' -d='ef' --output-folder .\modules\GDMK.CAH.Common --local-framework-ref --abp-path ..\..\..\..\abp\

--template module: 模块/服务模板

--no-ui: 不创建前端项目

-d: 指定数据库提供程序为ef.

--output-folder: 指定输出目录

--local-framework-ref: 使用本地abp框架

你可以自由设定模板选项,详情请参考abp-cli文档

我们只需要保留应用层,领域层,数据库,Api访问层以及各抽象层。将这些项目放在模块目录下,即当前位置(.\modules\GDMK.CAH.Common)

Common.Host项目作为微服务单独放置在服务目录中(一般为microservices)

看起来模块的目录结构如下

领域层

领域层中我们创建一个Tag实体、领域层服务和模型

Tag实体

public class Tag : AuditedEntity<long>, IMultiTenant
{
...
}

Tag领域层服务

public class TagManager<T> : DomainService
{
...
}

页面结构看起来像这样

应用层

在应用层抽象层中创建ITagAppService接口,以及各Dto类。

ITagAppService接口继承ICurdAppService,实现标签管理的增删改查功能

public interface ITagAppService : ICurdAppService<TagDto, TagDto, long, GetAllTagInput, GetAllTagInput, CreateTagInput, CreateTagInput>, IApplicationService
{
...
}

页面结构看起来像这样

应用层中创建标签管理的应用层服务TagAppService

TagAppService继承CurdAppServiceBase,实现ITagAppService接口

public class TagAppService : CurdAppServiceBase<Tag, TagDto, TagDto, long, GetAllTagInput, GetAllTagInput, CreateTagInput, CreateTagInput>, ITagAppService
{
...
}

配置AutoMapper

在CommonApplicationAutoMapperProfile中添加Tag的映射配置

public class CommonApplicationAutoMapperProfile : Profile
{
public CommonApplicationAutoMapperProfile()
{
/* You can configure your AutoMapper mapping configuration here.
* Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */
CreateMap<Tag.Tag, TagDto>(); CreateMap<TagDto, Tag.Tag>().Ignore(c => c.TenantId);
CreateMap<CreateTagInput, Tag.Tag>().IgnoreAuditedObjectProperties()
.Ignore(c => c.TenantId); }
}

数据库和仓储

在CommonDbContext中添加Tag的DbSet

public class CommonDbContext : AbpDbContext<CommonDbContext>, ICommonDbContext
{
/* Add DbSet for each Aggregate Root here. Example:
* public DbSet<Question> Questions { get; set; }
*/
public DbSet<Tag.Tag> Tag { get; set; } ...
}

在CommonDbContextModelCreatingExtensions中添加对Tag实体的配置

ConfigureByConvention会根据DataAnnotationAttributes为实体配置一些默认的属性,如Id为主键,Name为索引等,详情请参考Abp文档和EF文档

public static class CommonDbContextModelCreatingExtensions
{
public static void ConfigureCommon(
this ModelBuilder builder)
{
Check.NotNull(builder, nameof(builder)); builder.Entity<Tag.Tag>(b =>
{
b.ToTable(CommonDbProperties.DbTablePrefix + nameof(Tag.Tag), CommonDbProperties.DbSchema); b.ConfigureByConvention(); }); ...
}
}

在CommonEntityFrameworkCoreModule的ConfigureServices方法中,为Tag添加默认仓储

public class CommonEntityFrameworkCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<CommonDbContext>(options =>
{
/* Add custom repositories here. Example:
* options.AddRepository<Question, EfCoreQuestionRepository>();
*/
options.AddDefaultRepositories(includeAllEntities: true); }); }
}

控制器

添加控制器,配置路由

[Area(CommonRemoteServiceConsts.ModuleName)]
[RemoteService(Name = CommonRemoteServiceConsts.RemoteServiceName)]
[Route("api/Common/tag")]
public class TagController : CommonController<ITagAppService, TagDto, TagDto, long, GetAllTagInput, GetAllTagInput, CreateTagInput, CreateTagInput>, ITagAppService
{
private readonly ITagAppService _tagAppService; public TagController(ITagAppService tagAppService) : base(tagAppService)
{
_tagAppService = tagAppService;
} }

配置微服务

在服务目录中打开Common.Host项目,将CommonHttpApi,CommonApplication以及CommonEntityFrameworkCore模块添加到项目引用,并建立Abp模块的依赖关系

    [DependsOn(
typeof(AbpAutofacModule),
typeof(AbpAspNetCoreMvcModule),
typeof(AbpEntityFrameworkCoreSqlServerModule), typeof(CommonHttpApiModule),
typeof(CommonApplicationModule),
typeof(CommonEntityFrameworkCoreModule),
...
)]
public class CommonServiceHostModule : AbpModule

在launchSettings.json中指定端口号,此端口号不要跟其他服务的端口号冲突

"profiles": {
"CommonService.Host": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "http://localhost:44363",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
...
}

准备一些种子数据

public static List<Tag> tags = new List<Tag>()
{
new Tag() { Title = "医术高明" },
new Tag() { Title = "救死扶伤" },
new Tag() { Title = "心地仁慈" },
new Tag() { Title = "百治百效" },
new Tag() { Title = "白衣天使" },
new Tag() { Title = "手到病除" },
new Tag() { Title = "妙手回春" },
};

在CommonServiceDataSeeder创建种子数据

public class CommonServiceDataSeeder : IDataSeedContributor, ITransientDependency
{
private readonly IRepository<Tag.Tag, long> _tagRepository; public CommonServiceDataSeeder(
IRepository<Tag.Tag, long> tagRepository)
{
_tagRepository = tagRepository; } [UnitOfWork]
public virtual async Task SeedAsync(DataSeedContext context)
{
await _tagRepository.InsertManyAsync(StaticMember.tags);
} }

创建迁移

将Common.Host设置为启动项目,打开程序包管理器控制台选择Common.Host默认项目。

执行Add-Migration init命令和Update-Database命令

测试微服务

启动Common.Host,打开浏览器,输入http://localhost:44363/swagger/index.html

微服务注册

添加资源配置

AuthServerDataSeeder中添加identityServer4资源配置

添加Scopes

private async Task CreateApiScopesAsync()
{
...
await CreateApiScopeAsync("CommonService");
}

添加Resource

private async Task CreateApiResourcesAsync()
{
...
await CreateApiResourceAsync("CommonService", commonApiUserClaims); }

添加Client

private async Task CreateClientsAsync()
{
...
await CreateClientAsync(
"common-service-client",
commonScopes.Union(new[] { "InternalGateway", "IdentityService" }),
new[] { "client_credentials" },
commonSecret
);
}

配置网关

在内外网关的appsettings.json中添加Ocelot对微服务的路由转发

 {
"DownstreamPathTemplate": "/api/common/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 44363
}
],
"UpstreamPathTemplate": "/api/common/{everything}",
"UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ]
}

网关中添加对CommonHttpApi项目的引用,并配置Abp模块依赖

namespace BackendAdminAppGateway.Host
{
[DependsOn(
...
typeof(CommonHttpApiModule)
)]
public class BackendAdminAppGatewayHostModule : AbpModule ...

选择启动项目,将Common.Host微服务设置为启动

到此完成了新模块的配置工作

运行项目

可以通过网关访问Tag接口了

Volo.Abp升级小记(二)创建全新微服务模块的更多相关文章

  1. SpringCloud系列二:Restful 基础架构(搭建项目环境、创建 Dept 微服务、客户端调用微服务)

    1.概念:Restful 基础架构 2.具体内容 对于 Rest 基础架构实现处理是 SpringCloud 核心所在,其基本操作形式在 SpringBoot 之中已经有了明确的讲解,那么本次为 了清 ...

  2. ABP VNext从单体切换到微服务

    注:此处的微服务只考虑服务部分,不考虑内外层网关.认证等. ABP VNext从单体切换到微服务,提供了相当大的便利性,对于各模块内部不要做任何调整,仅需要调整承载体即可. ABP can help ...

  3. JHipster生成微服务架构的应用栈(二)- 认证微服务示例

    本系列文章演示如何用JHipster生成一个微服务架构风格的应用栈. 环境需求:安装好JHipster开发环境的CentOS 7.4(参考这里) 应用栈名称:appstack 认证微服务: uaa 业 ...

  4. maven 聚合工程 用spring boot 搭建 spring cloud 微服务 模块式开发项目

    项目的简单介绍: 项目采用maven聚合工程 用spring boot 搭建 spring cloud的微服务 模块式开发 项目的截图: 搭建开始: 能上图 我少打字 1.首先搭建maven的聚合工程 ...

  5. [Volo.Abp升级笔记]使用旧版Api规则替换RESTful Api以兼容老程序

    @ 目录 原理分析 开始改造 更换基类型 重写接口 替换默认规则 在微服务架构中的问题 Volo.Abp 配置应用层自动生成Controller,增删查改服务(CrudAppService)将会以RE ...

  6. Docker(二):微服务教程

    Docker 是一个容器工具,提供虚拟环境.很多人认为,它改变了我们对软件的认识. 站在 Docker 的角度,软件就是容器的组合:业务逻辑容器.数据库容器.储存容器.队列容器......,Docke ...

  7. 持续提升程序员幸福指数——使用abp vnext设计一款面向微服务的单体架构

    可能你会面临这样一种情况,在架构设计之前,你对业务不甚了解,需求给到的也模棱两可,这个时候你既无法明确到底是要使用单体架构还是使用微服务架构,如果使用单体,后续业务扩展可能带来大量修改,如果使用微服务 ...

  8. 微服务理论之二:面向微服务架构与传统架构、SOA对比,以及云化对比

    一.Monolith 网上对Microservice进行介绍的文章常常以Monolith作为开头,我也不会例外.原因是,知道了Monolith的不便之后才能更容易地理解Microservice架构模式 ...

  9. 二、springcloud微服务测试环境搭建

    版本说明: springcloud:Greenwich.SR3 springboot:2.1.8 1.构建步骤 1.1.microservicecloud整体父工程Project 新建父工程micro ...

  10. SpringCloud学习笔记(二):微服务概述、微服务和微服务架构、微服务优缺点、微服务技术栈有哪些、SpringCloud是什么

    从技术维度理解: 微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底 地去耦合,每一个微服务提供单个业务功能的服务,一个服务做一件事, 从技术角度看就是一种小而独立的处理过程,类 ...

随机推荐

  1. MySQL8.0 创建用户及授权 - 看这篇就足够了

    什么时候会用到 对接外系统时,需要给其余系统开放访问权限 本系统中,分权限管理数据,防止root权限删库跑路 mysql版本 MySql8.0+ 具体步骤 1.命令行进入MySql 使用 mysql ...

  2. MarkdownStudy02DOS窗口

    打开dos窗口 开始里面win系统 win+r,输入cmd 在任意文件下,按住shift+鼠标右键点击,在此处打开PowerShell窗口 资源管理器的地址栏前面加上cmd路径 管理员身份运行 常用的 ...

  3. Spring(Bean详解)

    GoF之工厂模式 GoF是指二十三种设计模式 GoF23种设计模式可分为三大类: 创建型(5个):解决对象创建问题. 单例模式 工厂方法模式 抽象工厂模式 建造者模式 原型模式 结构型(7个):一些类 ...

  4. Oracle问题:ORA-01565

    问题 oracle启动时报错,找不到spfile文件. ORA-01078: failure in processing system parameters ORA-01565: error in i ...

  5. w32模块模拟鼠标键盘操作

    win32api.keybd_event 该函数原型:keybd_event(bVk, bScan, dwFlags, dwExtraInfo) 第一个参数:虚拟键码(键盘键码对照表见附录): 第二个 ...

  6. pnpm 之降本增效

    作者:京东科技 于振京 受众简介 前端研发工程师 还在为npm i安装大量依赖等待时间较长,npm扁平化node_modules依赖版本冲突在苦恼吗,不用苦恼pnpm为你保驾护航 主要影响:安装依赖包 ...

  7. 简单的了解下 Fetch API 的工作原理

    一.简介 Fetch API是一种现代的Web API,提供了一种异步获取网络资源的方法.由于其简单性.灵活性和一致性,它已经成为Web应用程序中获取数据和资源的流行选择.在本文中,我们将深入探讨Fe ...

  8. 快速上手Linux核心命令(九):文件备份与压缩

    目录 tar 打包备份 gzip 压缩或解压文件 zip 打包和压缩文件 unzip 解压zip文件 scp 远程文件复制 rsync 文件同步工具 这期呢主要说一说Linux中文件备份与压缩命令,一 ...

  9. Jenkins-Email Extension Plugin邮件配置

    前言:此文为 Jenkins 2.346 版本 一.配置准备 1.安装 Email Extension Plugin 插件 二.配置邮件 Email Extension Plugin 部分 1.进入系 ...

  10. java镜子之反射篇

    文章目录 注解 内置注解 元注解 反射 类的初始化 类加载器 双亲委派机制 反射方法的使用 调用类的方法.成员变量.构造器等 总结 注解和反射是Java中非常重要的知识,一些优秀开源的框架都是大量运用 ...