在解决方案根目录添加common.props,这个文件的作用是可以配置项目文件全局的一些属性,如忽略警告,全局PackageReference,语言版本等。

<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>1.0.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<AbpProjectType>ms</AbpProjectType>
</PropertyGroup> <Target Name="NoWarnOnRazorViewImportedTypeConflicts" BeforeTargets="RazorCoreCompile">
<PropertyGroup>
<NoWarn>$(NoWarn);0436</NoWarn>
</PropertyGroup>
</Target> <ItemGroup>
<PackageReference Include="ConfigureAwait.Fody" Version="3.3.1" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.5.3">
<PrivateAssets>All</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup> </Project>

搭建服务

这里我们用ABP Cli来创建module模板,为什么用module模板呢,因为module模板最干净,没有别的依赖,app模板默认会添加ABP的基础模块,需要做删减,而module模板只需要添加需要的模块即可。

abp new FunShow.AdministrationService -t module --no-ui
abp new FunShow.IdentityService -t module --no-ui

创建完后删除多余的项目,authserver,DbMigrator, installer, mongoDb等,以及多余的文件,dockerfile,database目录,nuget.config,common.props等。
然后再把HttpApi.Host移到src目录。
最终结构如下

AdministrationService

首先我们先确定一下AdministrationService需要哪些ABP基础模块功能。
一个是Permission,一个是Feature,一个是Setting,还有Tenant。这里没包含审计日志是因为后续计划把日志模块独立一个服务。
我们按照模块依赖关系安装对应的模块包,以及在Module中DependsOn对应的模块

FunShow.AdministrationService.Domain.Shared

编辑项目文件,添加依赖

<Project Sdk="Microsoft.NET.Sdk">

	<Import Project="..\..\..\..\common.props" />

	<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>FunShow.AdministrationService</RootNamespace>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.Validation" Version="7.0.0" />
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.Shared" Version="7.0.0" />
<PackageReference Include="Volo.Abp.FeatureManagement.Domain.Shared" Version="7.0.0" />
<PackageReference Include="Volo.Abp.SettingManagement.Domain.Shared" Version="7.0.0" />
<PackageReference Include="Volo.Abp.TenantManagement.Domain.Shared" Version="7.0.0" />
</ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="7.0.1" />
</ItemGroup> <ItemGroup>
<EmbeddedResource Include="Localization\AdministrationService\*.json" />
<Content Remove="Localization\AdministrationService\*.json" />
</ItemGroup> </Project>

在Module添加模块依赖

using Volo.Abp.PermissionManagement;
using Volo.Abp.FeatureManagement;
using Volo.Abp.SettingManagement; [DependsOn(
typeof(AbpPermissionManagementDomainSharedModule),
typeof(AbpFeatureManagementDomainSharedModule),
typeof(AbpSettingManagementDomainSharedModule),
typeof(AbpValidationModule)
)]
public class AdministrationServiceDomainSharedModule : AbpModule

FunShow.AdministrationService.Domain

编辑项目文件,添加依赖

<Project Sdk="Microsoft.NET.Sdk">

	<Import Project="..\..\..\..\common.props" />

	<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<RootNamespace>FunShow.AdministrationService</RootNamespace>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="7.0.0" />
<PackageReference Include="Volo.Abp.Identity.Domain" Version="7.0.0" />
<PackageReference Include="Volo.Abp.PermissionManagement.Domain" Version="7.0.0" />
<PackageReference Include="Volo.Abp.FeatureManagement.Domain" Version="7.0.0" />
<PackageReference Include="Volo.Abp.SettingManagement.Domain" Version="7.0.0" />
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.OpenIddict" Version="7.0.0" />
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.Identity" Version="7.0.0" />
<PackageReference Include="Volo.Abp.TenantManagement.Domain" Version="7.0.0" />
<ProjectReference Include="..\FunShow.AdministrationService.Domain.Shared\FunShow.AdministrationService.Domain.Shared.csproj" />
</ItemGroup> </Project>

在Module添加模块依赖

using Volo.Abp.Domain;
using Volo.Abp.Modularity;
using Volo.Abp.FeatureManagement;
using Volo.Abp.PermissionManagement;
using Volo.Abp.PermissionManagement.Identity;
using Volo.Abp.PermissionManagement.OpenIddict;
using Volo.Abp.SettingManagement;
using Volo.Abp.TenantManagement;
using Volo.Abp.Identity; [DependsOn(
typeof(AbpDddDomainModule),
typeof(AbpIdentityDomainModule),
typeof(AdministrationServiceDomainSharedModule),
typeof(AbpPermissionManagementDomainModule),
typeof(AbpTenantManagementDomainModule),
typeof(AbpFeatureManagementDomainModule),
typeof(AbpSettingManagementDomainModule),
typeof(AbpPermissionManagementDomainOpenIddictModule),
typeof(AbpPermissionManagementDomainIdentityModule)
)]
public class AdministrationServiceDomainModule : AbpModule
{ }

FunShow.AdministrationService.EntityFrameworkCore

编辑项目文件,添加依赖

<Project Sdk="Microsoft.NET.Sdk">

	<Import Project="..\..\..\..\common.props" />

	<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<RootNamespace>FunShow.AdministrationService</RootNamespace>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.EntityFrameworkCore.PostgreSql" Version="7.0.0" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="7.0.0" />
<PackageReference Include="Volo.Abp.Identity.EntityFrameworkCore" Version="7.0.0" />
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" Version="7.0.0" />
<PackageReference Include="Volo.Abp.FeatureManagement.EntityFrameworkCore" Version="7.0.0" />
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore" Version="7.0.0" />
<PackageReference Include="Volo.Abp.TenantManagement.EntityFrameworkCore" Version="7.0.0" />
<ProjectReference Include="..\FunShow.AdministrationService.Domain\FunShow.AdministrationService.Domain.csproj" />
</ItemGroup> </Project>

在Module添加模块依赖

using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.PostgreSql;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.Modularity;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.TenantManagement.EntityFrameworkCore; [DependsOn(
typeof(AbpEntityFrameworkCorePostgreSqlModule),
typeof(AbpEntityFrameworkCoreModule),
typeof(AdministrationServiceDomainModule),
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpTenantManagementEntityFrameworkCoreModule),
typeof(AbpFeatureManagementEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpIdentityEntityFrameworkCoreModule)
)]
public class AdministrationServiceEntityFrameworkCoreModule : AbpModule

在module中替换DbContext

context.Services.AddAbpDbContext<AdministrationServiceDbContext>(options =>
{
/* Add custom repositories here. Example:
* options.AddRepository<Question, EfCoreQuestionRepository>();
*/ options.ReplaceDbContext<IPermissionManagementDbContext>();
options.ReplaceDbContext<ISettingManagementDbContext>();
options.ReplaceDbContext<IFeatureManagementDbContext>();
options.ReplaceDbContext<ITenantManagementDbContext>(); /* Remove "includeAllEntities: true" to create
* default repositories only for aggregate roots */
options.AddDefaultRepositories(includeAllEntities: true);
}); Configure<AbpDbContextOptions>(options =>
{
options.Configure<AdministrationServiceDbContext>(c =>
{
c.UseNpgsql(b =>
{
b.MigrationsHistoryTable("__AdministrationService_Migrations");
});
});
});

在DbContext中继承基础模块的IDbContext接口并实现

[ConnectionStringName(AdministrationServiceDbProperties.ConnectionStringName)]
public class AdministrationServiceDbContext : AbpDbContext<AdministrationServiceDbContext>, IAdministrationServiceDbContext,
IPermissionManagementDbContext,
ISettingManagementDbContext,
IFeatureManagementDbContext,
ITenantManagementDbContext

在DbContext中的OnModelCreating中添加模块的数据库初始化方法

protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder); builder.ConfigureAdministrationService();
builder.ConfigurePermissionManagement();
builder.ConfigureSettingManagement();
builder.ConfigureFeatureManagement();
builder.ConfigureTenantManagement();
}

FunShow.AdministrationService.Application.Contracts

编辑项目文件,添加nuget依赖

<Project Sdk="Microsoft.NET.Sdk">

	<Import Project="..\..\..\..\common.props" />

	<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>FunShow.AdministrationService</RootNamespace>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="7.0.0" />
<PackageReference Include="Volo.Abp.Authorization" Version="7.0.0" />
<PackageReference Include="Volo.Abp.PermissionManagement.Application.Contracts" Version="7.0.0" />
<PackageReference Include="Volo.Abp.Identity.Application.Contracts" Version="7.0.0" />
<PackageReference Include="Volo.Abp.FeatureManagement.Application.Contracts" Version="7.0.0" />
<PackageReference Include="Volo.Abp.SettingManagement.Application.Contracts" Version="7.0.0" />
<PackageReference Include="Volo.Abp.TenantManagement.Application.Contracts" Version="7.0.0" />
<ProjectReference Include="..\FunShow.AdministrationService.Domain.Shared\FunShow.AdministrationService.Domain.Shared.csproj" />
</ItemGroup> </Project>

在Module添加模块依赖

using Volo.Abp.Application;
using Volo.Abp.Authorization;
using Volo.Abp.Modularity;
using Volo.Abp.FeatureManagement;
using Volo.Abp.PermissionManagement;
using Volo.Abp.SettingManagement;
using Volo.Abp.TenantManagement; [DependsOn(
typeof(AbpPermissionManagementApplicationContractsModule),
typeof(AbpFeatureManagementApplicationContractsModule),
typeof(AbpSettingManagementApplicationContractsModule),
typeof(AbpTenantManagementApplicationContractsModule),
typeof(AdministrationServiceDomainSharedModule),
typeof(AbpDddApplicationContractsModule),
typeof(AbpAuthorizationModule)
)]
public class AdministrationServiceApplicationContractsModule : AbpModule

FunShow.AdministrationService.Application

编辑项目文件,添加依赖

<Project Sdk="Microsoft.NET.Sdk">

	<Import Project="..\..\..\..\common.props" />

	<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<RootNamespace>FunShow.AdministrationService</RootNamespace>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.AutoMapper" Version="7.0.0" />
<PackageReference Include="Volo.Abp.Ddd.Application" Version="7.0.0" />
<PackageReference Include="Volo.Abp.PermissionManagement.Application" Version="7.0.0" />
<PackageReference Include="Volo.Abp.FeatureManagement.Application" Version="7.0.0" />
<PackageReference Include="Volo.Abp.SettingManagement.Application" Version="7.0.0" />
<PackageReference Include="Volo.Abp.TenantManagement.Application" Version="7.0.0" />
<ProjectReference Include="..\FunShow.AdministrationService.Application.Contracts\FunShow.AdministrationService.Application.Contracts.csproj" />
<ProjectReference Include="..\FunShow.AdministrationService.Domain\FunShow.AdministrationService.Domain.csproj" />
</ItemGroup> </Project>

在Module添加模块依赖

using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Application;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
using Volo.Abp.FeatureManagement;
using Volo.Abp.PermissionManagement;
using Volo.Abp.SettingManagement;
using Volo.Abp.TenantManagement; [DependsOn(
typeof(AbpPermissionManagementApplicationModule),
typeof(AbpFeatureManagementApplicationModule),
typeof(AbpSettingManagementApplicationModule),
typeof(AbpTenantManagementApplicationModule),
typeof(AdministrationServiceDomainModule),
typeof(AdministrationServiceApplicationContractsModule),
typeof(AbpDddApplicationModule),
typeof(AbpAutoMapperModule)
)]
public class AdministrationServiceApplicationModule : AbpModule

FunShow.AdministrationService.HttpApi

编辑项目文件,添加依赖

<Project Sdk="Microsoft.NET.Sdk">

	<Import Project="..\..\..\..\common.props" />

	<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<RootNamespace>FunShow.AdministrationService</RootNamespace>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="7.0.0" />
<PackageReference Include="Volo.Abp.PermissionManagement.HttpApi" Version="7.0.0" />
<PackageReference Include="Volo.Abp.FeatureManagement.HttpApi" Version="7.0.0" />
<PackageReference Include="Volo.Abp.SettingManagement.HttpApi" Version="7.0.0" />
<PackageReference Include="Volo.Abp.TenantManagement.HttpApi" Version="7.0.0" />
<ProjectReference Include="..\FunShow.AdministrationService.Application.Contracts\FunShow.AdministrationService.Application.Contracts.csproj" />
</ItemGroup> </Project>

在Module添加模块依赖

using Localization.Resources.AbpUi;
using Microsoft.Extensions.DependencyInjection;
using FunShow.AdministrationService.Localization;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.FeatureManagement;
using Volo.Abp.PermissionManagement.HttpApi;
using Volo.Abp.SettingManagement;
using Volo.Abp.TenantManagement; [DependsOn(
typeof(AbpPermissionManagementHttpApiModule),
typeof(AbpFeatureManagementHttpApiModule),
typeof(AbpSettingManagementHttpApiModule),
typeof(AbpTenantManagementHttpApiModule),
typeof(AdministrationServiceApplicationContractsModule),
typeof(AbpAspNetCoreMvcModule))]
public class AdministrationServiceHttpApiModule : AbpModule

FunShow.AdministrationService.HttpApi.Client

编辑项目文件,添加nuget依赖

<Project Sdk="Microsoft.NET.Sdk">

	<Import Project="..\..\..\..\common.props" />

	<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>FunShow.AdministrationService</RootNamespace>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.Http.Client" Version="7.0.0" />
<PackageReference Include="Volo.Abp.PermissionManagement.HttpApi.Client" Version="7.0.0" />
<PackageReference Include="Volo.Abp.FeatureManagement.HttpApi.Client" Version="7.0.0" />
<PackageReference Include="Volo.Abp.SettingManagement.HttpApi.Client" Version="7.0.0" />
<ProjectReference Include="..\FunShow.AdministrationService.Application.Contracts\FunShow.AdministrationService.Application.Contracts.csproj" />
</ItemGroup> <ItemGroup>
<EmbeddedResource Include="**\*generate-proxy.json" />
<Content Remove="**\*generate-proxy.json" />
</ItemGroup> </Project>

在Module添加模块依赖

using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
using Volo.Abp.FeatureManagement;
using Volo.Abp.PermissionManagement;
using Volo.Abp.SettingManagement; [DependsOn(
typeof(AbpPermissionManagementHttpApiClientModule),
typeof(AbpFeatureManagementHttpApiClientModule),
typeof(AbpSettingManagementHttpApiClientModule),
typeof(AdministrationServiceApplicationContractsModule),
typeof(AbpHttpClientModule))]
public class AdministrationServiceHttpApiClientModule : AbpModule

FunShow.AdministrationService.HttpApi.Host

编辑项目文件,添加依赖

<Project Sdk="Microsoft.NET.Sdk.Web">

	<Import Project="..\..\..\..\common.props" />

	<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<RootNamespace>FunShow.AdministrationService</RootNamespace>
<PreserveCompilationReferences>true</PreserveCompilationReferences>
<UserSecretsId>FunShow.AdministrationService-c2d31439-b723-48e2-b061-5ebd7aeb6010</UserSecretsId>
</PropertyGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\shared\FunShow.Shared.Localization\FunShow.Shared.Localization.csproj" />
<ProjectReference Include="..\..\..\..\shared\FunShow.Shared.Hosting.Microservices\FunShow.Shared.Hosting.Microservices.csproj" />
<ProjectReference Include="..\FunShow.AdministrationService.Application\FunShow.AdministrationService.Application.csproj" />
<ProjectReference Include="..\FunShow.AdministrationService.EntityFrameworkCore\FunShow.AdministrationService.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\FunShow.AdministrationService.HttpApi\FunShow.AdministrationService.HttpApi.csproj" />
</ItemGroup> <ItemGroup>
<Compile Remove="Logs\**" />
<Content Remove="Logs\**" />
<EmbeddedResource Remove="Logs\**" />
<None Remove="Logs\**" />
</ItemGroup> </Project>

在module中添加模块依赖

[DependsOn(
typeof(FunShowSharedLocalizationModule),
typeof(FunShowSharedHostingMicroservicesModule),
typeof(AdministrationServiceApplicationModule),
typeof(AdministrationServiceHttpApiModule),
typeof(AdministrationServiceEntityFrameworkCoreModule)
)]
public class AdministrationServiceHttpApiHostModule : AbpModule

然后编辑Module中的ConfigureServices方法,OnApplicationInitialization方法,OnPostApplicationInitializationAsync方法

public override void ConfigureServices(ServiceConfigurationContext context)
{
//You can disable this setting in production to avoid any potential security risks.
Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true; // Enable if you need these
// var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration(); JwtBearerConfigurationHelper.Configure(context, "AdministrationService");
SwaggerConfigurationHelper.ConfigureWithAuth(
context: context,
authority: configuration["AuthServer:Authority"],
scopes: new
Dictionary<string, string> /* Requested scopes for authorization code request and descriptions for swagger UI only */
{
{"AdministrationService", "AdministrationService API"}
},
apiTitle: "AdministrationService API"
);
context.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder
.WithOrigins(
configuration["App:CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.Trim().RemovePostFix("/"))
.ToArray()
)
.WithAbpExposedHeaders()
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
} public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment(); if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseCorrelationId();
app.UseAbpRequestLocalization();
app.UseAbpSecurityHeaders();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthentication();
app.UseAbpClaimsMap();
app.UseAuthorization();
app.UseSwagger();
app.UseAbpSwaggerUI(options =>
{
var configuration = context.ServiceProvider.GetRequiredService<IConfiguration>();
options.SwaggerEndpoint("/swagger/v1/swagger.json", "AdministrationService API");
options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]);
});
app.UseAbpSerilogEnrichers();
app.UseAuditing();
app.UseUnitOfWork();
app.UseConfiguredEndpoints(endpoints => endpoints.MapMetrics());
} public async override Task OnPostApplicationInitializationAsync(ApplicationInitializationContext context)
{
using (var scope = context.ServiceProvider.CreateScope())
{
await scope.ServiceProvider
.GetRequiredService<AdministrationServiceDatabaseMigrationChecker>()
.CheckAndApplyDatabaseMigrationsAsync();
}
}

JwtBearerConfigurationHelper.Configure()和SwaggerConfigurationHelper.ConfigureWithAuth()就是我们在shared模块中封装的JWT和Swagger配置操作。

编辑Program

public async static Task<int> Main(string[] args)
{
var assemblyName = typeof(Program).Assembly.GetName().Name; SerilogConfigurationHelper.Configure(assemblyName); try
{
Log.Information($"Starting {assemblyName}.");
var builder = WebApplication.CreateBuilder(args);
builder.Host
.AddAppSettingsSecretsJson()
.UseAutofac()
.UseSerilog();
await builder.AddApplicationAsync<AdministrationServiceHttpApiHostModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
await app.RunAsync();
return 0;
}
catch (Exception ex)
{
Log.Fatal(ex, $"{assemblyName} terminated unexpectedly!");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}

SerilogConfigurationHelper.Configure就是shared项目中共用的日志配置操作
修改appsettings.json

{
"App": {
"SelfUrl": "https://localhost:44367",
"CorsOrigins": "https://localhost:44325,https://localhost:44353"
},
"AuthServer": {
"Authority": "https://localhost:44322",
"RequireHttpsMetadata": "true",
"SwaggerClientId": "WebGateway_Swagger"
},
"RemoteServices": {
"AbpIdentity": {
"BaseUrl": "https://localhost:44388/",
"UseCurrentAccessToken": "false"
}
},
"IdentityClients": {
"Default": {
"GrantType": "client_credentials",
"ClientId": "FunShow_AdministrationService",
"ClientSecret": "1q2w3e*",
"Authority": "https://localhost:44322",
"Scope": "IdentityService"
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"AdministrationService": "Server=localhost,1434;Database=FunShow_Administration;User Id=sa;password=myPassw0rd;MultipleActiveResultSets=true"
},
"StringEncryption": {
"DefaultPassPhrase": "IOiW1AE6WjSf2KIH"
},
"Redis": {
"Configuration": "localhost:6379"
},
"RabbitMQ": {
"Connections": {
"Default": {
"HostName": "localhost"
}
},
"EventBus": {
"ClientName": "FunShow_AdministrationService",
"ExchangeName": "FunShow"
}
},
"ElasticSearch": {
"Url": "http://localhost:9200"
}
}

修改Shared.Hosting.Microservices

因为我们AdministrationService中很多数据是共用的,所以为了方便其他服务,我们把AdministrationService的数据操作也抽出来,每个服务可以直接操作AdministrationService的数据库读取数据。
在项目文件添加AdministrationService的EfCore项目引用

<ItemGroup>
<ProjectReference Include="..\..\services\administration\src\Walk.AdministrationService.EntityFrameworkCore\Walk.AdministrationService.EntityFrameworkCore.csproj" />
</ItemGroup>

module添加依赖

typeof(AdministrationServiceEntityFrameworkCoreModule)

到这我们AdministrationService的配置基本就完成了。
但是现在还不能启动服务,因为我们数据库还没迁移,并且还没对接上认证服务。
接下来我们在实现IdentityService,然后搭建认证服务和网关服务即可初步完成最初的服务搭建。

IdentityService

和AdministrationService不同的是,这个服务我们只需要依赖Identity和OpenIddict的基础模块。
配置方式和AdministrationService基本一致。
这里我就不重复了,以免水文。

LoggingService

上面我们说了打算把日志抽离单独一个服务,并且其他服务写日志通过消息队列写入数据库。
处理方法参考ABP商业版的文档https://docs.abp.io/en/commercial/latest/guides/extracting-module-as-microservice
不同的是由于Audit-Logging Management是商业版模块,所以我们的服务只依赖Volo.Abp.AuditLogging的开源模块,基本也满足了。日志相关的操作我们后续再自定义一些API提供对接。

以发布事件写入审核日志

在Shared.Hosting.Microservices项目中创建Logging目录,添加类EventBasedAuditingStore

using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Uow; namespace FunShow.Shared.Hosting.Microservices.Logging
{
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IAuditingStore))]
public class EventBasedAuditingStore : IAuditingStore, ITransientDependency
{
private readonly IDistributedEventBus _distributedEventBus;
private readonly ILogger<EventBasedAuditingStore> _logger; public EventBasedAuditingStore(IDistributedEventBus distributedEventBus, ILogger<EventBasedAuditingStore> logger)
{
_distributedEventBus = distributedEventBus;
_logger = logger;
} [UnitOfWork]
public async Task SaveAsync(AuditLogInfo auditInfo)
{
_logger.LogInformation("Publishing audit log creation..."); // EntityEntry will break serialization so we remove it
for (var i = 0; i < auditInfo.EntityChanges.Count; i++)
{
auditInfo.EntityChanges[i].EntityEntry = null;
} await _distributedEventBus.PublishAsync(auditInfo);
}
}
}

在 LoggingService.HttpApi.Host 下命名的处理程序:AuditCreationHandler

using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
using Volo.Abp.AuditLogging;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Uow; namespace FunShow.LoggingService.HttpApi.Host.Handlers
{
public class AuditCreationHandler : IDistributedEventHandler<AuditLogInfo>, ITransientDependency
{
private readonly IAuditLogRepository _auditLogRepository;
private readonly IAuditLogInfoToAuditLogConverter _converter;
private readonly ILogger<AuditCreationHandler> _logger; public AuditCreationHandler(IAuditLogRepository auditLogRepository, IAuditLogInfoToAuditLogConverter converter,
ILogger<AuditCreationHandler> logger)
{
_converter = converter;
_logger = logger;
_auditLogRepository = auditLogRepository;
} [UnitOfWork]
public async Task HandleEventAsync(AuditLogInfo eventData)
{
try
{
_logger.LogInformation("Handling Audit Creation...");
await _auditLogRepository.InsertAsync(await _converter.ConvertAsync(eventData));
}
catch (Exception ex)
{
_logger.LogWarning("Could not save the audit log object ...");
_logger.LogException(ex, LogLevel.Error);
}
}
}
}

这就完成了日志服务的搭建。

下一章我们来搭建认证服务和网关服务

ABP微服务系列学习-搭建自己的微服务结构(二)的更多相关文章

  1. ABP微服务系列学习-搭建自己的微服务结构(一)

    在原本的结构里面,由于默认服务引用的都是ABP原生的模块,所以结构目录里面没有包含modules目录,这里我们添加一个modules目录,用于存放我们的自定义模块.在shared里面,我们再抽一个Ev ...

  2. ABP微服务系列学习-搭建自己的微服务结构(四)

    上篇我们实现了认证服务和网关服务,基本我们的基础服务已经完成了,接下来我们才需要做服务的数据迁移.这里我们需要使用EF的CodeFirst模式.通过DotnetCli的命令去操作: dotnet ef ...

  3. ABP微服务系列学习-搭建自己的微服务结构(三)

    上一篇我们基础服务初步搭建完毕,接下来我们整一下认证和网关. 搭建认证服务 认证服务的话,ABP CLI生成的所有模板都包括了一个AuthServer.我们直接生成模板然后微调一下就可以直接用了. a ...

  4. ABP微服务系列学习-使用Tye启动微服务

    Tye是微软开源的一款开发人员工具, 能够用于简化微服务以及分布式应用程序的开发.测试以及部署过程.Tye 的首要目标是简化微服务的开发,具体方式包括仅用一行命令执行多项服务.在容器中使用依赖项目,以 ...

  5. springcloud微服务架构搭建

    SpringCloud微服务框架搭建 一.微服务架构 1.1什么是分布式 不同模块部署在不同服务器上 作用:分布式解决网站高并发带来问题 1.2什么是集群 多台服务器部署相同应用构成一个集群 作用:通 ...

  6. SprngCloud微服务框架搭建(一)

    参照来源 :https://blog.csdn.net/forezp/article/details/70148833 1.简介 目前来说,SpringCloud是比较完整的微服务解决方案框架.不像其 ...

  7. Spring Cloud 微服务中搭建 OAuth2.0 认证授权服务

    在使用 Spring Cloud 体系来构建微服务的过程中,用户请求是通过网关(ZUUL 或 Spring APIGateway)以 HTTP 协议来传输信息,API 网关将自己注册为 Eureka ...

  8. 【spring colud】spring cloud微服务项目搭建【spring boot2.0】

    spring cloud微服务项目搭建 =================================== 示例版本: 1.spring boot 2.0版本 2.开发工具 IntellJ IDE ...

  9. 简单Spring Cloud 微服务框架搭建

    微服务是现在比较流行的技术,对于程序猿而言,了解并搭建一个基本的微服务框架是很有必要滴. 微服务包含的内容非常多,一般小伙伴们可以根据自己的需求不断添加各种组件.框架. 一般情况下,基本的微服务框架包 ...

  10. java架构之路-(微服务专题)初步认识微服务与nacos初步搭建

    历史演变: 以前我们都是一个war包,包含了很多很多的代码,反正我开始工作的时候做的就是这样的项目,一个金融系统,代码具体多少行记不清楚了,内部功能超多,但是实际能用到的不多,代码冗余超大,每次部署大 ...

随机推荐

  1. 推荐一款功能齐全的开源MES/万界星空科技mes

    推荐一款功能齐全的开源MES 万界星空科技商业开源MES可以提供包括制造数据管理.计划排程管理.生产调度管理.库存管理.质量管理.人力资源管理.工作中心/设备管理.工具工装管理.采购管理.成本管理.项 ...

  2. 2023.2 IDEA安装激活教程

    1.下载安装IntelliJ IDEA 先去官网下载,我这里下载的是最新版本的2023.2,测试过2023最新版本以及2022版本以上的版本没问题. 安装然后打开 提示要输入激活码,先关闭应用,等下再 ...

  3. 【K8S系列】如何高效查看 k8s日志

    序言 你只管努力,其他交给时间,时间会证明一切. 文章标记颜色说明: 黄色:重要标题 红色:用来标记结论 绿色:用来标记一级论点 蓝色:用来标记二级论点 Kubernetes (k8s) 是一个容器编 ...

  4. JavaScript this 绑定详解

    函数内 this 绑定 函数内this的绑定和函数定义的位置没有关系,和调用的方式和调用位置有关系,函数内的this是在被调用执行时被绑定的. this的具体绑定规则 this 绑定基本包含下面4种绑 ...

  5. 一些JavaSE学习过程中的思路整理(三)(主观性强,持续更新中...)

    目录 一些JavaSE学习过程中的思路整理(三)(主观性强,持续更新中...) Java线程同步的几种常见情况分析 由简单到复杂的几种单例模式写法 死锁的实现与破解 使用lambda表达式化简代码 J ...

  6. 从1天到10分钟的超越,华为云DRS在背后做了这些

    摘要:华为云DRS助力一汽-大众BI平台实时查看报表,提升数字化决策能力. 本文分享自华为云社区<分钟级查看报表,华为云&一汽-大众,让商机时刻被洞见>,作者:GaussDB 数据 ...

  7. Error: Could not find or load main class org.elasticsearch.tools.java_version_checker.JavaVersionChecker

    把elasticsearch目录换到不属于root目录的其他目录就行了

  8. socket.d.js v2.3.4 支持"微信"、"uniapp"

    Socket.D 是基于"事件"和"语义消息""流"的网络应用层协议.有用户说,"Socket.D 之于 Socket,尤如 Vu ...

  9. HanLP — HMM隐马尔可夫模型 -- 语料库

    隐马尔可可夫模型(Hidden Markov Model,HMM)是统计模型,用于描述一个含有隐含未知参数的马尔可夫过程. HMM由初始概率分布.状态转移概率分布和观测概率分布确定. BMES =&g ...

  10. selenium 访问无等待

    from selenium.webdriver.common.desired_capabilities import DesiredCapabilities desired_capabilities ...