🦖

.NET8 AutoMapperを使用したObjectのマッピング

2024/01/14に公開

1.この記事の範囲

オブジェクトの相互間変換の補助としてAutoMapperライブラリを使用する場合の、基本実装を記載。

2.背景

ASP.NET Core 8 Web APIで開発されたアプリケーションがある。
各レイヤー間でデータ操作やModelのやり取りする処理の重複があり、マッピング規則を作成し処理を簡素化したい。

3.内容

3-1. AutoMapperとは

AutoMapperは仕様と規則に基づいて、オブジェクト同士をマップするためのライブラリ。
例えば、DBのデータを保持し、ビジネスロジックを通してAPI用のModelに変換、MVCならViewModelに繰り返し入れ直す処理などを、AutoMapperを使用してコードを削減や規則化する。
https://automapper.org/

3-2. 準備

NuGetパッケージをプロジェクトに追加
AutoMapper
AutoMapper.Extensions.Microsoft.DependencyInjection

3-3. 実装

a. Entity

DBから取得した情報をアプリケーションに適した形式のModelに変換する。

Infrastructures layer

Users.cs
public class Users:IDate
{
    public int UserId { get; set; }
    public required string UserName { get; set; }
    public required string FirstName { get; set; }
    public required string LastName { get; set; }
    public required string Email { get; set; }
    public DateTime Birthday { get; set; }
    public DateTimeOffset CreatedAt { get; set; }
    public DateTimeOffset? UpdatedAt { get; set; }
    public DateTimeOffset? DeletedAt { get; set; }
}

business layer

User.cs
public class User
{
    public int UserId { get; set; }
    public required string FirstName { get; set; }
    public required string LastName { get; set; }
    public required string Email { get; set; }
    public int BirthYear { get; set; }
    public int BirthMonth { get; set; }
    public int BirthDay { get; set; }
    public string? OccupationName { get; set; }
}

b. AutoMapperプロファイルの作成

AutoMapperを使用して2つのモデルをマッピングするために、マッピング設定を定義する。AutoMapperに一方のモデルから他方へデータを転送する方法を指示する。

・CreateMap<Users, User>()でUsersからUserへのマッピングを定義
・ForMemberメソッドを使って、個々のプロパティのマッピングまたは無視されるかを指定

AutoMapperProfile.cs
using AutoMapper;
using System;

public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Users, User>()
            .ForMember(dest => dest.UserId, opt => opt.MapFrom(src => src.UserId))
            .ForMember(dest => dest.FirstName, opt => opt.MapFrom(src => src.FirstName))
            .ForMember(dest => dest.LastName, opt => opt.MapFrom(src => src.LastName))
            .ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.Email))
            .ForMember(dest => dest.BirthYear, opt => opt.MapFrom(src => src.Birthday.Year))
            .ForMember(dest => dest.BirthMonth, opt => opt.MapFrom(src => src.Birthday.Month))
            .ForMember(dest => dest.BirthDay, opt => opt.MapFrom(src => src.Birthday.Day))
	    .ForMember(dest => dest.OccupationName, opt => opt.Ignore())
    }
}

C. Program.csの設定

アプリケーションの起動時にAutoMapperが初期化され、依存注入を通じてアプリケーション全体で利用できるように設定する。

・サービスコレクションにAutoMapperを追加

AutoMapperConfig.cs
using AutoMapper;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// 他のサービスの設定..

// AutoMapperの設定
builder.Services.AddAutoMapper(typeof(AutoMapperProfile));

var app = builder.Build();

app.Run();

d. マッピングの実行

AutoMapperのインスタンス(IMapper)を使用して、UsersオブジェクトをUserオブジェクトにマッピングする。

UserService.cs
using AutoMapper;

public class YourService
{
    private readonly IMapper _mapper;

    public YourService(IMapper mapper)
    {
        _mapper = mapper;
    }

    public User ConvertUsersToUser(Users users)
    {
        // UsersからUserへのマッピングを実行
        User user = _mapper.Map<User>(users);
        return user;
    }
}

4. まとめ

AutoMapperを使用することで、オブジェクトの相互変換ルールを明確化でき簡易化できる。
独自のConverterのコードを頻繁に記載する場合は、AutoMapperを使用するとコードの保守の点からメリットがあった。

Discussion