Anto Subash.

Published on

Administration Services - .NET Microservice with ABP - Part 3

This is third post of the series: .NET Microservice with ABP

Posts in the Series

Part 1. Initial Setup

Part 2. Shared Project

Part 3. Administration Service (this post)

Part 4. Identity Service

Part 5. SaaS Service

Part 6. DB Migration

Part 7. Yarp and Tye

Part 8. Identity server and Angular App

Part 9. Distributed event bus

Part 10. Docker and CI/CD

Part 11. Add a New service

Part 12. Central Logging

Table of contents

Setup Administration service

Adminstration service is where we uses Audit log, feature, settings and permission management modules. We will use a separate database to store everything in the administration service.

Add the shared project as a reference to the host

We need to add shared project as the reference to the Administration service. once this is added we can do some cleanup in the host module of the administration.

1<ProjectReference Include="..\..\..\..\shared\Tasky.Shared.Hosting\Tasky.Shared.Hosting.csproj" />

Update the connection string

User ID=postgres;Password=postgres;Host=localhost;Port=5432;Database=AdministrationService;Pooling=false;

Update the AdministrationServiceHttpApiHostModule

Update the depends on with the shared module. Once the shared module is added then we can removed most of the modules in the host module. Below is how the final depends on looks like.

1[DependsOn(
2    typeof(TaskyHostingModule),
3    typeof(AdministrationServiceApplicationModule),
4    typeof(AdministrationServiceEntityFrameworkCoreModule),
5    typeof(AdministrationServiceHttpApiModule),
6)]

Remove the things which are configured in the shared project.

Create the DbContextFactory in the EntityFrameworkCore project

We need to create a Factory class for the DbContext so that we can create migration in the EfCore project. this is necessary to build the configuration form the host project.

1using System.IO;
2using Microsoft.EntityFrameworkCore;
3using Microsoft.EntityFrameworkCore.Design;
4using Microsoft.Extensions.Configuration;
5
6namespace Tasky.AdministrationService.EntityFrameworkCore;
7
8public class AdministrationServiceDbContextFactory : IDesignTimeDbContextFactory<AdministrationServiceDbContext>
9{
10    public AdministrationServiceDbContext CreateDbContext(string[] args)
11    {
12        var builder = new DbContextOptionsBuilder<AdministrationServiceDbContext>()
13            .UseNpgsql(GetConnectionStringFromConfiguration());
14
15        return new AdministrationServiceDbContext(builder.Options);
16    }
17
18    private static string GetConnectionStringFromConfiguration()
19    {
20        return BuildConfiguration()
21            .GetConnectionString(AdministrationServiceDbProperties.ConnectionStringName);
22    }
23
24    private static IConfigurationRoot BuildConfiguration()
25    {
26        var builder = new ConfigurationBuilder()
27            .SetBasePath(
28                Path.Combine(
29                    Directory.GetParent(Directory.GetCurrentDirectory())?.Parent!.FullName!,
30                    $"host{Path.DirectorySeparatorChar}Tasky.AdministrationService.HttpApi.Host"
31                )
32            )
33            .AddJsonFile("appsettings.json", false);
34
35        return builder.Build();
36    }
37}

Update the AdministrationServiceDbContext

In the DbContext we need to updated it with the DbContext of the modules. We have added 4 modules in the administration service and all modules have a db context. So we have to inherit from the db context of the modules. this is add the DBSet of the modules to the administration module.

1using Microsoft.EntityFrameworkCore;
2using Volo.Abp.Data;
3using Volo.Abp.EntityFrameworkCore;
4using Volo.Abp.AuditLogging.EntityFrameworkCore;
5using Volo.Abp.FeatureManagement.EntityFrameworkCore;
6using Volo.Abp.PermissionManagement.EntityFrameworkCore;
7using Volo.Abp.SettingManagement.EntityFrameworkCore;
8using Volo.Abp.AuditLogging;
9using Volo.Abp.FeatureManagement;
10using Volo.Abp.PermissionManagement;
11using Volo.Abp.SettingManagement;
12
13namespace Tasky.AdministrationService.EntityFrameworkCore;
14
15[ConnectionStringName(AdministrationServiceDbProperties.ConnectionStringName)]
16public class AdministrationServiceDbContext : AbpDbContext<AdministrationServiceDbContext>,
17    IPermissionManagementDbContext,
18    ISettingManagementDbContext,
19    IFeatureManagementDbContext,
20    IAuditLoggingDbContext,
21    IAdministrationServiceDbContext
22{
23    /* Add DbSet for each Aggregate Root here. Example:
24     * public DbSet<Question> Questions { get; set; }
25     */
26
27    public AdministrationServiceDbContext(DbContextOptions<AdministrationServiceDbContext> options)
28        : base(options)
29    {
30    }
31
32    public DbSet<AuditLog> AuditLogs { get; set; }
33    public DbSet<FeatureValue> FeatureValues { get; set; }
34    public DbSet<PermissionGrant> PermissionGrants { get; set; }
35    public DbSet<Setting> Settings { get; set; }
36
37    protected override void OnModelCreating(ModelBuilder builder)
38    {
39        base.OnModelCreating(builder);
40
41        builder.ConfigureAdministrationService();
42        builder.ConfigurePermissionManagement();
43        builder.ConfigureSettingManagement();
44        builder.ConfigureAuditLogging();
45        builder.ConfigureFeatureManagement();
46    }
47}

Update the AdministrationServiceEntityFrameworkCoreModule

This is the final setup before creating the migration. we have to inform the ef core that we are using postgres as database. we can do that configuring AbpDbContextOptions and replace the db context of the modules with the administration db context.

1using Microsoft.Extensions.DependencyInjection;
2using Volo.Abp.EntityFrameworkCore;
3using Volo.Abp.Modularity;
4using Volo.Abp.AuditLogging.EntityFrameworkCore;
5using Volo.Abp.FeatureManagement.EntityFrameworkCore;
6using Volo.Abp.PermissionManagement.EntityFrameworkCore;
7using Volo.Abp.SettingManagement.EntityFrameworkCore;
8using System;
9
10namespace Tasky.AdministrationService.EntityFrameworkCore;
11
12[DependsOn(
13    typeof(AdministrationServiceDomainModule),
14    typeof(AbpEntityFrameworkCoreModule)
15)]
16[DependsOn(typeof(AbpAuditLoggingEntityFrameworkCoreModule))]
17[DependsOn(typeof(AbpFeatureManagementEntityFrameworkCoreModule))]
18[DependsOn(typeof(AbpPermissionManagementEntityFrameworkCoreModule))]
19[DependsOn(typeof(AbpSettingManagementEntityFrameworkCoreModule))]
20public class AdministrationServiceEntityFrameworkCoreModule : AbpModule
21{
22    public override void ConfigureServices(ServiceConfigurationContext context)
23    {
24        Configure<AbpDbContextOptions>(options =>
25        {
26            options.UseNpgsql();
27        });
28        
29        AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
30        context.Services.AddAbpDbContext<AdministrationServiceDbContext>(options =>
31        {
32            options.ReplaceDbContext<IPermissionManagementDbContext>();
33            options.ReplaceDbContext<ISettingManagementDbContext>();
34            options.ReplaceDbContext<IFeatureManagementDbContext>();
35            options.ReplaceDbContext<IAuditLoggingDbContext>();
36
37            options.AddDefaultRepositories(true);
38        });
39    }
40}

Prepare for the migration

Add the ef core design nuget for the migrations.

1<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.1">
2    <PrivateAssets>all</PrivateAssets>
3    <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
4</PackageReference>

Once this is created delete EntityFrameworkCore folder can be created from the host project.

Migration

To create migrations

dotnet ef migrations add Init

To update database

dotnet ef database update

Repo: https://github.com/antosubash/AbpMicroservice