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


    简介

    互联网产品主要分为两大类,分别是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.Ddd.Domain
    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 Volo.Abp.EntityFrameworkCore
    PM> Install-Package Volo.Abp.EntityFrameworkCore.SqlServer
    PM> 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、EntityFrameworkCore层、HttpApi层
    PM> Install-Package Microsoft.EntityFrameworkCore.Tools
    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(AbpEntityFrameworkCoreModule)
        )]
        public class BusinessEntityFrameworkCoreModule : AbpModule
        {
            public override void ConfigureServices(ServiceConfigurationContext context)
            {
                context.Services.AddAbpDbContext<BusinessDbContext>(options =>
                {
                    options.AddDefaultRepositories(includeAllEntities: true);
                });
            }
        }
    

    添加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(AbpEntityFrameworkCoreSqlServerModule),
            typeof(AbpPermissionManagementEntityFrameworkCoreModule),
            typeof(AbpSettingManagementEntityFrameworkCoreModule),
            typeof(AbpAuditLoggingEntityFrameworkCoreModule),
            typeof(AbpTenantManagementEntityFrameworkCoreModule),
            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();
                ConfigureSql();
                ConfigureCache(configuration);
                ConfigureVirtualFileSystem(context);
                ConfigureRedis(context, configuration, hostingEnvironment);
                ConfigureCors(context, configuration);
                ConfigureSwaggerServices(context);
            }
    
            private void ConfigureSql()
            {
                Configure<AbpDbContextOptions>(options =>
                {
                    options.UseSqlServer();
                });    
            }
    
            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

  • 相关阅读:
    Springboot单元测试(MockBean||SpyBean)
    使用 Mockito 单元测试 – 教程
    spring结合mockito
    Spatis service单元测试: 使用mock mapper的方式
    单元测试Mockito中的Mock和Spy
    强大的Mockito测试框架
    Mockito单测,mock service层的mapper
    Mockito教程
    SetupFactory 制作安装包
    fiddler的一些记录
  • 原文地址:https://www.cnblogs.com/william-xu/p/12612434.html
Copyright © 2020-2023  润新知