[从0到1搭建ABP微服务] - 搭建Business微服务

简介

互联网产品主要分为两大类,分别是B端产品和C端产品。B端产品主要管业务(Business)代表系统有ERP、WMS、CRM等,C端产品主要管消费者(Consumer)代表主要就是各种电商网站如淘宝、京东等。本篇文章将基于ABP框架搭建一个Business微服务,后续我会逐渐添加一些实用的业务功能到Business服务中。

新建项目

在MicroServices目录中创建一个新的 asp.net core 项目Business.Host

空项目结果如下:

DDD分层

在空项目中使用DDD设计思想搭建分层架构,在Business解决方案中添加以下新的类库

安装模块组件

Domain层

在空Business.Domain层中安装ABP组件

PM> Install-Package Volo.Abp.Localization

PM> Install-Package Volo.Abp.Validation

Application.Contracts层

在空Business.Application.Contracts层中安装ABP组件并引用Domain层

PM> Install-Package Volo.Abp.Ddd.Application

Application层

在空Business.Application层中安装ABP组件和引用Application.Contracts层

PM> Install-Package Volo.Abp.AutoMapper

EntityFrameworkCore层

在空Business.EntityFrameworkCore层中安装EF Core、ABP组件和引用Domain层

PM> Install-Package Microsoft.EntityFrameworkCore.Design

PM> Install-Package Microsoft.EntityFrameworkCore.Tools

PM> Install-Package Volo.Abp.EntityFrameworkCore

PM> Install-Package Volo.Abp.EntityFrameworkCore.SqlServer

Volo.Abp.AuditLogging.EntityFrameworkCore

PM> Install-Package Volo.Abp.PermissionManagement.EntityFrameworkCore

PM> Install-Package Volo.Abp.SettingManagement.EntityFrameworkCore

PM> Install-Package Volo.Abp.TenantManagement.EntityFrameworkCore

HttpApi层

在空Business.HttpApi层中安装ABP组件和引用Application.Contracts层

PM> Install-Package Volo.Abp.AspNetCore.Mvc

HttpApi.Client层

在空Business.HttpApi.Client层中安装ABP组件和引用Application.Contracts层

PM> Install-Package Volo.Abp.Http.Client

Host层

在空Business.Host层中安装ids4、redis、serilog、swagger、ABP组件和引用Application、HttpApi层

PM> Install-Package IdentityServer4.AccessTokenValidation -Version 3.0.1

PM> Install-Package Serilog.AspNetCore -Version 3.2.0

PM> Install-Package Serilog.Sinks.File -Version 4.1.0

PM> Install-Package Serilog.Sinks.Elasticsearch -Version 6.5.0

PM> Install-Package Swashbuckle.AspNetCore -Version 5.0.0

PM> Install-Package Microsoft.Extensions.Caching.StackExchangeRedis -Version 3.1.0

PM> Install-Package Microsoft.AspNetCore.DataProtection.StackExchangeRedis -Version 3.1.0

PM> Install-Package Volo.Abp.Autofac

PM> Volo.Abp.AspNetCore.MultiTenancy

PM> Install-Package Volo.Abp.AspNetCore.Serilog

PM> Install-Package Volo.Abp.Caching

配置Module

添加BusinessDomainModule

在Business.Domain层中添加BusinessDomainModule.cs

    [DependsOn(
        typeof(AbpLocalizationModule)
    )]
    public class BusinessDomainModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            Configure<AbpVirtualFileSystemOptions>(options =>
            {
                options.FileSets.AddEmbedded<BusinessDomainModule>("Business");
            });

            Configure<AbpLocalizationOptions>(options =>
            {
                options.Resources
                    .Add<BusinessResource>("en")
                    .AddBaseTypes(typeof(AbpValidationResource))
                    .AddVirtualJson("/Localization/Business");
            });

            Configure<AbpMultiTenancyOptions>(options =>
            {
                options.IsEnabled = MultiTenancyConsts.IsEnabled;
            });
        }
    }

添加BusinessApplicationContractsModule

在Business.Application.Contracts层中添加BusinessApplicationContractsModule.cs

    [DependsOn(
        typeof(AbpDddApplicationModule)
    )]
    public class BusinessApplicationContractsModule : AbpModule
    {

    }

添加BusinessApplicationModule

在Business.Application层中添加BusinessApplicationModule.cs

    [DependsOn(
        typeof(BusinessDomainModule),
        typeof(BusinessApplicationContractsModule),
        typeof(AbpAutoMapperModule)
    )]
    public class BusinessApplicationModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            Configure<AbpAutoMapperOptions>(options =>
            {
                options.AddMaps<BusinessApplicationModule>();
            });
        }
    }

添加BusinessEntityFrameworkCoreModule

在Business.EntityFrameworkCore层中添加Business.EntityFrameworkCore

    [DependsOn(
        typeof(BusinessDomainModule),
        typeof(AbpPermissionManagementEntityFrameworkCoreModule),
        typeof(AbpSettingManagementEntityFrameworkCoreModule),
        typeof(AbpEntityFrameworkCoreSqlServerModule),
        typeof(AbpAuditLoggingEntityFrameworkCoreModule),
        typeof(AbpTenantManagementEntityFrameworkCoreModule)
    )]
    public class BusinessEntityFrameworkCoreModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddAbpDbContext<BusinessDbContext>(options =>
            {
                options.AddDefaultRepositories(includeAllEntities: true);
            });

            Configure<AbpDbContextOptions>(options =>
            {
                options.UseSqlServer();
            });
        }
    }

添加BusinessHttpApiModule

在Business.HttpApi层中添加Business.HttpApi.cs

    [DependsOn(
        typeof(BusinessApplicationContractsModule),
        typeof(AbpAspNetCoreMvcModule)
    )]
    public class BusinessHttpApiModule : AbpModule
    {
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            PreConfigure<IMvcBuilder>(mvcBuilder =>
            {
                mvcBuilder.AddApplicationPartIfNotExists(typeof(BusinessHttpApiModule).Assembly);
            });
        }
    }

添加BusinessHttpApiClientModule

在Business.HttpApi.Client层中添加Business.HttpApi.Client.cs

    [DependsOn(
        typeof(BusinessApplicationContractsModule)
    )]
    public class BusinessHttpApiClientModule : AbpModule
    {
        public const string RemoteServiceName = "Business";

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddHttpClientProxies(
                typeof(BusinessApplicationContractsModule).Assembly,
                RemoteServiceName
            );
        }
    }

添加BusinessHostModule

在Business.Host层中添加BusinessHostModule.cs

    [DependsOn(
        typeof(AbpAutofacModule),
        typeof(BusinessHttpApiModule),
        typeof(BusinessApplicationModule),
        typeof(AbpAspNetCoreMultiTenancyModule),
        typeof(AbpAspNetCoreSerilogModule)
    )]
    public class BusinessHostModule : AbpModule
    {
        private const string DefaultCorsPolicyName = "Default";

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            var configuration = context.Services.GetConfiguration();
            var hostingEnvironment = context.Services.GetHostingEnvironment();

            ConfigureConventionalControllers();
            ConfigureAuthentication(context, configuration);
            ConfigureLocalization();
            ConfigureCache(configuration);
            ConfigureVirtualFileSystem(context);
            ConfigureRedis(context, configuration, hostingEnvironment);
            ConfigureCors(context, configuration);
            ConfigureSwaggerServices(context);
        }

        private void ConfigureCache(IConfiguration configuration)
        {
            Configure<AbpDistributedCacheOptions>(options =>
            {
                options.KeyPrefix = "Business:";
            });
        }

        private void ConfigureVirtualFileSystem(ServiceConfigurationContext context)
        {
            var hostingEnvironment = context.Services.GetHostingEnvironment();

            if (hostingEnvironment.IsDevelopment())
            {
                Configure<AbpVirtualFileSystemOptions>(options =>
                {
                    options.FileSets.ReplaceEmbeddedByPhysical<BusinessDomainModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Business.Domain"));
                    options.FileSets.ReplaceEmbeddedByPhysical<BusinessApplicationContractsModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Business.Application.Contracts"));
                    options.FileSets.ReplaceEmbeddedByPhysical<BusinessApplicationModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Business.Application"));
                });
            }
        }

        private void ConfigureConventionalControllers()
        {
            Configure<AbpAspNetCoreMvcOptions>(options =>
            {
                options.ConventionalControllers.Create(typeof(BusinessApplicationModule).Assembly);
            });
        }

        private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
        {
            context.Services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = configuration["AuthServer:Authority"];
                    options.RequireHttpsMetadata = true;
                    options.ApiName = "BusinessService";
                });
        }

        private static void ConfigureSwaggerServices(ServiceConfigurationContext context)
        {
            context.Services.AddSwaggerGen(
                options =>
                {
                    options.SwaggerDoc("v1", new OpenApiInfo { Title = "Business Service API", Version = "v1" });
                    options.DocInclusionPredicate((docName, description) => true);
                });
        }

        private void ConfigureLocalization()
        {
            Configure<AbpLocalizationOptions>(options =>
            {
                options.Languages.Add(new LanguageInfo("cs", "cs", "?e?tina"));
                options.Languages.Add(new LanguageInfo("en", "en", "English"));
                options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
                options.Languages.Add(new LanguageInfo("tr", "tr", "Türk?e"));
                options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
                options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
            });
        }

        private void ConfigureRedis(
            ServiceConfigurationContext context,
            IConfiguration configuration,
            IWebHostEnvironment hostingEnvironment)
        {
            context.Services.AddStackExchangeRedisCache(options =>
            {
                options.Configuration = configuration["Redis:Configuration"];
            });

            if (!hostingEnvironment.IsDevelopment())
            {
                var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
                context.Services
                    .AddDataProtection()
                    .PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
            }
        }

        private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
        {
            context.Services.AddCors(options =>
            {
                options.AddPolicy(DefaultCorsPolicyName, builder =>
                {
                    builder
                        .WithOrigins(
                            configuration["App:CorsOrigins"]
                                .Split(",", StringSplitOptions.RemoveEmptyEntries)
                                .Select(o => o.RemovePostFix("/"))
                                .ToArray()
                        )
                        .WithAbpExposedHeaders()
                        .SetIsOriginAllowedToAllowWildcardSubdomains()
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials();
                });
            });
        }

        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();

            app.UseCorrelationId();
            app.UseVirtualFiles();
            app.UseRouting();
            app.UseCors(DefaultCorsPolicyName);
            app.UseAuthentication();
            if (MultiTenancyConsts.IsEnabled)
            {
                app.UseMultiTenancy();
            }
            app.UseAuthorization();
            app.UseAbpRequestLocalization();

            app.UseSwagger();
            app.UseSwaggerUI(options =>
            {
                options.SwaggerEndpoint("/swagger/v1/swagger.json", "Business Service API");
            });

            app.UseAuditing();
            app.UseAbpSerilogEnrichers();
            app.UseMvcWithDefaultRouteAndArea();
        }

种子文件和配置文件

配置文件如下:

{
  "App": {
    "CorsOrigins": "https://*.abc.com,http://localhost:9527"
  },
  "ConnectionStrings": {
    "Default": "Server=localhost;Database=ABP;User Id=sa;Password=123456;",
    "Business": "Server=localhost;Database=Business;User Id=sa;Password=123456;"
  },
  "Redis": {
    "Configuration": "localhost"
  },
  "AuthServer": {
    "Authority": "https://localhost:53362"
  }
}

启动

Ctrl+F5运行

测试API

在swagger中测试/api/test接口

测试成功

代码地址:https://github.com/WilliamXu96/ABP-MicroService

文章目录:https://www.cnblogs.com/william-xu/p/12537155.html

原文地址:https://www.cnblogs.com/william-xu/p/12612434.html

时间: 2024-11-05 19:04:16

[从0到1搭建ABP微服务] - 搭建Business微服务的相关文章

自主搭建CI/CD,为vNext微服务开发保驾护航

简介 微服务开发中自动化.持续化工程十分重要,在成熟的CI/CD环境中项目团队可以灵活分配,大大提供团队效率.如果还不了解什么是CI/CD,可以先查看相关文章,这里主要介绍环境的搭建,相关原理就不过多搬书了. 开始之前 目前主流的ci/cd环境都是基于容器化管理的,所以想要搭建这一环境必须熟练docker操作.版本控制选择git,构建工具选择Jenkins,所以开始前需要先掌握这些技术. 安装docker Ubuntu 18.04 docker安装 docker安装方式有多种,存储库安装方式如下

SpringCloud微服务搭建(适合初学者)

Spring Cloud 微服务简介 1. 单体应用优化 1.1 可使用SOA面向服务架构(将每个模块分开,某个模块出问题了,不会影响其他模块)    1.2 如果某个服务于其他服务有调用关系,那么就需用到ESB(企业服务总线) 2. 微服务架构 2.1 将单体应用切分为小服务单元 3. Spring Cloud 3.1 是一个工具箱 3.2 基于SpringBoot,封装了Netflix的框架 3.3 将Netflix与Spring容器进行整合 4. Spring Cloud整合的Netfli

微服务搭建中遇到的问题

前言 现在我所在的xx公司要重构用户系统.旧用户系统是一个单一应用系统.下游的各个系统通过调用用户系统实现对用户查询.登录.校验.菜单的管理.为了适应新的企业级架构模式,用微服务架构对旧用户系统进行重构. 其实,从单一应用系统到微服务架构的搭建,锻炼的是重构一个旧的单一应用项目的思路:单一应用==>微服务架构应用. 过程如下: 1.从熟悉原有的项目:需求文档.操作手册.数据库设计文档.对外接口.页面原型(对系统进行实操).对外接口的调用原理.(这里因为我对用户系统不是很熟悉,所以需要从各个方面熟

(高版本)ELK(Elasticsearch + Logstash + Kibana)服务服务搭建

一.ELK是什么鬼? ELK实际上是三个工具的集合,Elasticsearch + Logstash + Kibana,这三个工具组合形成了一套实用.易用的监控架构,很多公司利用它来搭建可视化的海量日志分析平台. 1. ElasticSearch ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引

整合spring cloud云架构 - commonservice-sso服务搭建(一)

前面几篇我们已经介绍了Spring Cloud和oauth2的知识点,今天我们要利用Spring Cloud和oauth2进行commonservice-sso服务搭建,本节我们只是搭建commonservice-sso的基础平台,闲话少说,直接将步骤记录下来: 1. 创建maven项目commonservice-sso,其中pom.xml文件配置如下: Xml代码   <?xml version="1.0" encoding="UTF-8"?> <

微服务的入门级微框架Spring Boot快速入门

详情请交流  QQ  709639943 00.微服务的入门级微框架Spring Boot快速入门 00.基于java的微信公众号二次开发视频教程 00.leetcode 算法 面试 00.北风网 零基础到数据(大数据)分析专家-首席分析师 00.快速上手JMeter 00.Jmeter 00.2017年Java web开发工程师成长之路 00.R语言速成实战 00.R语言数据分析实战 00.Python+Django+Ansible Playbook自动化运维项目实战 00.Java深入微服务

Spring Cloud云架构 - commonservice-sso服务搭建(一)

前面几篇我们已经介绍了Spring Cloud和oauth2的知识点,今天我们要利用Spring Cloud和oauth2进行commonservice-sso服务搭建,本节我们只是搭建commonservice-sso的基础平台,闲话少说,直接将步骤记录下来: 1. 创建maven项目commonservice-sso,其中pom.xml文件配置如下: <?xml version="1.0" encoding="UTF-8"?> <project

(十五)Java B2B2C o2o多用户商城-commonservice-sso服务搭建(一)

前面几篇我们已经介绍了Spring Cloud和oauth2的知识点,今天我们要利用Spring Cloud和oauth2进行commonservice-sso服务搭建,本节我们只是搭建commonservice-sso的基础平台,闲话少说,直接将步骤记录下来: 创建maven项目commonservice-sso,其中pom.xml文件配置如下: <?xml version="1.0" encoding="UTF-8"?> <project xm

ASP.NET Core 微服务初探[1]:服务发现之Consul

在传统单体架构中,由于应用动态性不强,不会频繁的更新和发布,也不会进行自动伸缩,我们通常将所有的服务地址都直接写在项目的配置文件中,发生变化时,手动改一下配置文件,也不会觉得有什么问题.但是在微服务模式下,服务会更细的拆分解耦,微服务会被频繁的更新和发布,根据负载情况进行动态伸缩,以及受资源调度影响而从一台服务器迁移到另一台服务器等等.总而言之,在微服务架构中,微服务实例的网络位置变化是一种常态,服务发现也就成了微服务中的一个至关重要的环节. 服务发现是什么 其实,服务发现可以说自古有之,我们每