[從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.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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章