본문 바로가기

c#/ASP.NET CORE

ASP.NET CORE AutoMapper 사용법

ASP.NET CORE를 사용하다 보면 객체 매핑을 하는 코드를 계속 작성해야 하는 번거로움이 있습니다.

이럴때 AutoMapper라는 확장을 설치하여서 객체 매핑의 번거로움을 줄입니다.

위의 AutoMapper.Extensions.Microsoft.DependencyInjection 패키지를 설치하면 

AutoMapper의 기능들을 사용 할 수 있게됩니다.  

AutoMapper는 기본적으로 Profile클래스를 상속받아서 해당 상속받은 클래스에서 매핑을 할 model객체와 dto를 CreateMap 이라는 메서드를 통하여 컨테이너에 등록 할 수 있습니다.

public abstract class BaseCountryDto
{
    [Required]
    public string Name { get; set; }
 
    public string ShortName { get; set; }
}
public class CountryDto : BaseCountryDto
{
    public int Id { get; set; }
    public List<HotelDto> Hotels { get; set; }
}
public class CreateCountryDto : BaseCountryDto
{
}

public class UpdateCountryDto : BaseCountryDto
{
    public int Id { get; set; }

}

 

public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string ShortName { get; set; }
 
 
    public virtual IList<Hotel> Hotels { get; set; }
}
public class MapperConfig : Profile
   {
       public MapperConfig()
       {
           CreateMap<Country, CreateCountryDto>().ReverseMap();
           CreateMap<Country, GetCountryDto>().ReverseMap();
           CreateMap<Country, CountryDto>().ReverseMap();
           CreateMap<Country, UpdateCountryDto>().ReverseMap();
 
           CreateMap<Hotel, HotelDto>().ReverseMap();
           CreateMap<Hotel, CreateHotelDto>().ReverseMap();
           CreateMap<ApiUserDto, ApiUser>().ReverseMap();
       }
   }

그리고 program.cs에 위에서 작성한 MapperConfig를 서비스에 등록합니다.

builder.Services.AddAutoMapper(typeof(MapperConfig));//컨테이너 오토매퍼등록

CreateMap 메서드는 원본 객체를 앞 복사할 대상을 뒤에 넣으면 복사가 됩니다.

CreateMap<TSource, TDestination>();

 이때 ReverseMap()을 사용하면 역방향으로 매핑이 가능한데 이렇게 사용하는 이유는 아래와 같습니다.

1. 양방향 바인딩: 주로 웹 애플리케이션에서 폼에서 데이터를 받아오거나 사용자 입력을 처리할 때 사용됩니다. 사용자가 입력한 데이터를 받아오는 데 사용된 클래스와 화면에 표시하는 데 사용되는 클래스 간의 매핑을 정의할 때, 역방향 매핑을 통해 수정된 데이터를 다시 사용할 수 있습니다.

2. 양방향 데이터 전송: 어떤 경우에는 데이터를 읽을 때 뿐만 아니라 수정할 때도 필요한 경우가 있습니다. 역방향 매핑을 사용하면 대상 클래스에서 소스 클래스로의 매핑도 자동으로 이루어져서, 대상 클래스에서 수정된 데이터를 소스 클래스로 다시 매핑할 수 있습니다.

3. 일관성 유지: 역방향 매핑을 사용하면 양방향으로 매핑되는 클래스 간에 일관성을 유지하기 쉽습니다. 하나의 클래스에서 다른 클래스로 매핑 규칙을 정의하면, 그 규칙을 수정할 때 두 클래스에 대한 매핑이 일관되게 유지됩니다.

컨트롤러에 IMapper라는 서비스를 가져와서 주입시키면 아래 예시와 같이 사용이 가능합니다.

private readonly IMapper _mapper;
private readonly ICountriesRepository _countriesRepository;
 
public CountriesController(IMapper mapper, ICountriesRepository countriesRepository) //programcs에서 Service에 DBcontext를 등록해서 
{
 
    this._mapper = mapper;
    this._countriesRepository = countriesRepository;
}
// GET: api/Countries/5
[HttpGet("{id}")]
public async Task<ActionResult<CountryDto>> GetCountry(int id)
{
    var country = await _countriesRepository.GetDetails(id);
 
    if (country == null)
    {
        return NotFound();
    }
 
    var countryDto = _mapper.Map<CountryDto>(country);
 
    return Ok(countryDto);
}

위 코드처럼 country객체를 가져와 CountryDto객체를 매핑시켜서 CountryDto객체를 return할 수 있습니다.

[HttpPost]
     [Authorize]
     public async Task<ActionResult<Country>> PostCountry(CreateCountryDto createCountryDto)
     {
         //Map뒤에 제네릭으로 원형데이터타입넣어줌
         var country = _mapper.Map<Country>(createCountryDto);
 
         await _countriesRepository.AddAsync(country);
 
         return CreatedAtAction("GetCountry", new { id = country.Id }, country);
     }

 

   아니면 위와같이  CreteCountryDto객체를 가지고 Country 객체와 매핑할수 있습니다.

mapper를 쓰지않았다면 아래처럼 Country 객체를 일일히 매핑해야 하지만 mapper 를 쓰면 위처럼 간단하게 매핑이 가능하게 됩니다.

[HttpPost]
[Authorize]
public async Task<ActionResult<Country>> PostCountry(CreateCountryDto createCountryDto)
{
    Country country = new Country
    {    
        Name = createCountryDto.Name,
        ShortName = createCountryDto.ShortName,
    };    
 
    await _countriesRepository.AddAsync(country);
 
    return CreatedAtAction("GetCountry", new { id = country.Id }, country);
}

'c# > ASP.NET CORE' 카테고리의 다른 글

ASP.NET CORE HTTP health Check  (0) 2024.05.20
ASP.NET CORE 전역 에러 처리 Global Error Exception  (0) 2024.03.09