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 |