ABP 프레임워크에서 모듈 생성 및 독립형 데이터베이스 마이그레이션 구성 방법

ABP 솔루션 초기 설정

ABP CLI를 사용하면 빠르게 새로운 애플리케이션을 시작할 수 있습니다. 다음 명령어를 통해 Blazor 기반의 다중 계층 구조 솔루션을 생성합니다.

abp new MainApp -u blazor --tiered

생성 후에는 .DbMigrator.HttpApi.Host 프로젝트를 각각 실행하여 초기 데이터베이스 설정과 API 서버 동작을 확인합니다. 이 과정에서 appsettings.json 파일 내의 연결 문자열을 환경에 맞게 수정해야 하며, 기본 인증 및 권한 관리 기능은 이미 포함되어 있어 로그인 화면까지 정상적으로 노출됩니다.

모듈 프로젝트 추가

기존 방식처럼 별도로 모듈을 생성한 후 수동으로 솔루션을 통합하는 것은 오류 발생 가능성이 높습니다. 대신 ABP CLI는 기존 솔루션에 직접 모듈을 추가하는 기능을 제공합니다.

abp add-module MyModule --new --add-to-solution-file

해당 명령은 현재 디렉터리에 modules/MyModule 폴더를 생성하고, 관련 모든 프로젝트를 메인 솔루션에 자동 등록합니다. 또한 필요한 종속성 참조도 함께 처리하므로 통합 작업이 훨씬 간소화됩니다.

엔티티 모델 설계 및 EF Core 구성

새로운 비즈니스 로직을 위한 도메인 모델을 정의합니다. 예를 들어 Product 엔티티를 생성했다면, 아래 절차를 따릅니다.

  • 모듈의 도메인 계층에 Product.cs 클래스 작성
  • MyModule.EntityFrameworkCore 프로젝트 내 MyModuleDbContext에 다음 코드 추가:
public DbSet<Product> Products { get; set; }
  • MyModuleDbContextModelCreatingExtensions.cs 파일에서 모델 매핑 활성화:
modelBuilder.Entity<Product>(b =>
{
    b.ToTable("Products");
    b.Property(x => x.Name).IsRequired().HasMaxLength(128);
});

독립된 데이터베이스 마이그레이션 환경 구성

모듈이 메인 앱과 분리된 데이터베이스를 사용하도록 하려면 전용 DbContext와 팩토리 클래스가 필요합니다. 먼저 MainApp.EntityFrameworkCore 프로젝트 내에 EntityFrameworkCore/MyModule 디렉터리를 생성합니다.

MyModuleMigrationsDbContext.cs

public class MyModuleMigrationsDbContext : AbpDbContext<MyModuleMigrationsDbContext>
{
    public MyModuleMigrationsDbContext(DbContextOptions<MyModuleMigrationsDbContext> options)
        : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.ConfigureMyModule();
    }
}

MyModuleMigrationsDbContextFactory.cs

public class MyModuleMigrationsDbContextFactory : IDesignTimeDbContextFactory<MyModuleMigrationsDbContext>
{
    public MyModuleMigrationsDbContext CreateDbContext(string[] args)
    {
        var config = BuildConfiguration();

        var builder = new DbContextOptionsBuilder<MyModuleMigrationsDbContext>()
            .UseSqlServer(config.GetConnectionString("MyModule"));

        return new MyModuleMigrationsDbContext(builder.Options);
    }

    private static IConfigurationRoot BuildConfiguration()
    {
        return new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json")
            .Build();
    }
}

마지막으로 MainApp.DbMigratorMainApp.HttpApi.Hostappsettings.json에 다음과 같은 연결 문자열을 추가합니다.

"ConnectionStrings": {
  "MainApp": "...",
  "MyModule": "Server=localhost;Database=MyModuleDb;..."
}

데이터베이스 마이그레이션 실행

EF Core CLI를 사용해 마이그레이션 파일을 생성합니다. 커맨드 라인에서 MainApp.EntityFrameworkCore 디렉터리로 이동 후 다음 명령을 수행합니다.

dotnet ef migrations add InitialMyModule --context MyModuleMigrationsDbContext --output-dir Migrations/MyModule

생성된 마이그레이션 스크립트는 Migrations/MyModule 경로에 저장되어 메인 앱의 마이그레이션과 충돌하지 않습니다. 적용은 아래 명령으로 완료합니다.

dotnet ef database update --context MyModuleMigrationsDbContext

API 컨트롤러 자동 등록

모듈의 애플리케이션 서비스가 API 엔드포인트로 노출되도록 하려면 MainAppHttpApiHostModule.cs에서 컨벤션 기반 컨트롤러 생성 규칙에 모듈 어셈블리를 추가해야 합니다.

Configure<AbpAspNetCoreMvcOptions>(options =>
{
    options.ConventionalControllers.Create(typeof(MainAppApplicationModule).Assembly);
    options.ConventionalControllers.Create(typeof(MyModuleApplicationModule).Assembly); // 추가
});

매핑 예외 처리

DTO와 엔티티 간 AutoMapper 구성 시, CreateUpdateProductDto → Product 매핑에서 Id 필드 누락으로 인해 예외가 발생할 수 있습니다. 이를 방지하기 위해 매핑 규칙에 무시 조건을 명시합니다.

var mappingConfig = context.Services.GetRequiredService<IMapperConfigurationExpression>();
mappingConfig.CreateMap<CreateUpdateProductDto, Product>()
             .Ignore(x => x.Id);

이렇게 하면 입력 DTO에 Id가 없더라도 매핑 과정에서 문제가 발생하지 않습니다.

프론트엔드 통합 (Blazor)

모듈의 Blazor UI는 modules/MyModule/src/MyModule.Blazor에 위치하며, 메인 앱과 물리적으로 분리되어 있습니다. 컴포넌트 및 메뉴 항목은 모듈 내에서 독립적으로 개발되며, 솔루션 재빌드 시 자동으로 통합됩니다. 브라우저에서 새로운 메뉴 링크가 나타나고, 빈 페이지부터 시작하여 점진적으로 기능을 구현할 수 있습니다.

태그: ABP Framework Entity Framework Core Blazor database migration Modular Architecture

6월 10일 01:51에 게시됨