首页 > 其他分享 >ABP微服务系列学习-搭建自己的微服务结构(二)

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

时间:2023-02-28 15:13:08浏览次数:45  
标签:Abp 服务 Volo ABP typeof 系列学习 using AdministrationService FunShow

在解决方案根目录添加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目录。
最终结构如下
image.pngimage.png

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,服务,Volo,ABP,typeof,系列学习,using,AdministrationService,FunShow
From: https://www.cnblogs.com/fanshaoO/p/17164310.html

相关文章

  • flask部署windows服务器
    fromflaskimportFlaskapp=Flask(__name__)@app.route("/")defhello():return"HelloWorld!"pipinstalltornadofromtornado.httpserverimportHTTP......
  • 问题[] 远程连接腾讯云服务器上的mysql
    困扰我两个月的问题终于解决啦.问题: 腾讯云服务上的mariadb,在本地win7连不上数据库...用户授权.GRANTALL PRIVILEGESON*.* TO 'aaa'@'%' IDENTIFIEDBY......
  • 谷歌Gmail邮箱开启SMTP/IMAP服务流程[转载]
    前言:本篇专门定向讲解谷歌Gmail邮箱,如何开通SMTP协议的流程,在讲篇幅前,我需要你确定3件事:1.你已经有谷歌账号了2.你很清楚自己为什么想要开通SMTP服务3.你已经掌握一定......
  • 灾难性的服务器域控制器的恢复(原创)
    在c:\winnt\ntds下线删除除ntds.dit外的所有文件,再用ntdsutilfilesrepair进行修复目录数据库执行语义数据库分析。为此,请在命令提示符处键入以下命令,包括引号:ntdsutil"se......
  • 虚拟主机中,如何知道服务器上已安装的所有字体的列表?
    很久以前,我曾写过一篇“网页中如何获取客户端系统已安装的所有字体?”之后,有一些朋友问我:在使用虚拟主机的情况下,如何获取服务器上已安装字体的列表?实际上,非常简单!在支持asp.......
  • java网络编程-线程池服务端
    上篇文章我们借助线程实现了服务端可以服务多个客户端,但是每次请求进来都创建新线程也是一种很大的资源消耗,线程上下文切换都会影响性能。本次我们继续对服务端进行改造,引......
  • java网络编程-并发服务端
    上次的服务端一次只能接受一个客户端的连接,性能实在堪忧,我们对服务端进行了改造,每接到一个客户端的请求,就新建一个线程,让新线程跟客户端进行交互,主线程可以继续等待其他客......
  • 服务器的稳定性对网站的响应
        在确保了服务器安全性的前提条件下,就需要对服务器的稳定性和响应速度进行调查了。要是服务器不稳定或者是响应速度比较慢的话,就非常容易导致宕机或者加载时间太......
  • java网络编程-客户端和服务器
    基于java.net包,实现一个简单的服务端和客户端,客户端只管发,服务端只管收缺点:服务端只能处理一个客户端的请求,因为服务端是单线程的。一次只能与一个客户端进行消息通信服......
  • tomcat源码分析(一)如何启动服务
    从startup.sh入手os400=falsecase"`uname`"inOS400*)os400=true;;esacPRG="$0"while[-h"$PRG"];dols=`ls-ld"$PRG"`link=`expr"$ls":'.*->\(......