首页 > 其他分享 >Volo.Abp升级小记(二)创建全新微服务模块

Volo.Abp升级小记(二)创建全新微服务模块

时间:2023-06-09 14:56:48浏览次数:52  
标签:... Volo Abp Tag Common 模块 new public 小记

@

目录
假设有一个按照官方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,Tag,Common,模块,new,public,小记
From: https://www.cnblogs.com/jevonsflash/p/17469191.html

相关文章

  • JVM调休小记
    首先要明白为什么要进行JVM调优?对于高QPS(每秒查询率,一台服务器能够响应的查询请求的次数)的项目来说其将会在堆内存中高度频繁地创建对象,将会触发较为频繁的GC可以使用jstat命令查看GC的情况jstat-gcutilpid1000每隔1秒打印一次GC统计信息首先要找到java进程的pid通过内置的jps命......
  • 前缀和 & 技巧小记
    前缀和子数组的元素之和:一维前缀和子矩阵的元素之和:二维前缀和前缀和+哈希表:寻找和为target的子数组 子数组的元素之和:一维前缀和前缀和适用于快速、频繁地计算一个索引区间内的元素之和。intres=0;//存储区间[left,right]之和for(inti=left;i<=right;i++)......
  • 【JavaScript】setTimeout 和 setInterval 小记
    项目setTimeoutsetInterval名称一次性定时器循环定时器相同在规定延迟时间再执行某个操作在规定延迟时间再执行某个操作区别只能定时一次可以一直循环执行下去......
  • 设计模式小记
    创建型模式(CreationalPatterns):工厂模式(FactoryPattern):通过工厂方法创建对象,隐藏具体实现细节,例如创建不同类型的按钮。//简单工厂模式classButtonFactory{createButton(type){switch(type){case'submit':returnnewSubmitButton();......
  • ABP - 缓存模块(1)
    1.与.NETCore缓存的关系和差异ABP框架中的缓存系统核心包是Volo.Abp.Caching,而对于分布式缓存的支持,abp官方提供了基于Redis的方案,需要安装Volo.Abp.Caching.StackExchangeRedis集成包。默认的情况下,在我们使用ABPCLI创建ABP框架模板项目的时候已经集成了这个包......
  • go-shadowsw问题小记
    Golangshadows是指在Go语言中,一个变量在内部作用域中被另一个同名同类型的变量声明而隐藏的情况。这种情况可能导致一些意想不到的结果,比如返回错误的值或者引用错误的变量。1funcBadRead(f*os.File,buf[]byte)errerror{2for{3n,err:=f.Read(bu......
  • .net core Abp定时任务实现
     publicclassUseTimeJob:Job//重点是继承Job {publicreadonlyIUserCourseJobTimeService_userCourseJobTimeService;publicreadonlyIOrganizationAppService_organizationAppService;privatereadonlyIOfflineCourseLiveRecordServic......
  • Vue3 尝试小记
    1.安装vue使用npm或yarn安装Vue3:#npmnpminstallvue@next#yarnyarnaddvue@next2.创建项目文件夹在命令行中,输入以下命令,在根目录下创建一个项目文件夹:mkdirmy-vue3-project3.初始化package.json使用npminit命令,在该目录中创建package.json文件:npm......
  • 5.30 模拟赛小记
    A.求1-N每个数的约数集合求1-N每个数字约数集合,显然用试除法不合适,在这里用倍数法。对于每个数字找到范围内它的倍数,则这个倍数就可以标记约数了。但是这是syoj,作为一个成熟的oier,你要学会高效输出,指本题卡scanf,需要优化输出,否则你只能得到40pts的好成绩。对了今......
  • ABP - 依赖注入(2)
    依赖注入的使用构造方法注入这是将服务注入类的最常用方法,是将依赖项注入类的首选方式,也是微软推崇的模式。这样,除非提供了所有构造方法注入的依赖项,否则无法构造类,显示的声明了类必需的服务,使开发人员一目了然。publicclassBookAppService:ApplicationService{priv......