WPF Prism에서 AutoMapper 사용하기
AutoMapper
AutoMapper는 서로 다른 두 클래스를 보다 쉽게 매핑하기 위해 사용하는 라이브러리이다. 내 경우(그리고 많은 오픈소스 프로젝트의 경우) 모델과 DTO 사이의 매핑을 손쉽게 처리하기 위해 주로 사용된다.
Prism
Prism 프레임워크, 또는 라이브러리1는 이전 포스트에서 자세히 다룬 바 있다. 다시 간략하게 정리하자면 MVVM 기반 프로젝트 개발을 더 쉽게 할 수 있도록 도와주는 프레임워크이다.
Prism에서 AutoMapper DI하기
ASP.NET 프로젝트에서 AutoMapper 사용은 정말 쉽다. 애초에 AutoMapper에서 확장 메서드를 제공하기 때문에 서비스를 구성할 때 해당 메서드를 호출하고, AutoMapper.Profile
을 상속받은 클래스를 만들어 아무 곳에다가 배치해놓은 뒤 실행하면 된다.
그러나 Prism용 확장 메서드는 자체적으로 제공되지 않으므로 직접 만들어 써야 한다.
IAutoMapperProvider interface
일단 DI를 위해 사용할 인터페이스부터 구성한다.
public interface IAutoMapperProvider
{
IMapper GetMapper();
}
AutoMapperProvider class
이제 위 인터페이스를 상속한 AutoMapperProvider
클래스를 작성한다.
public class AutoMapperProvider : IAutoMapperProvider
{
private readonly MapperConfiguration _configuration;
public AutoMapperProvider(IContainerProvider containerProvider)
{
_configuration = new MapperConfiguration(config =>
{
config.ConstructServicesUsing(containerProvider.Resolve);
config.AddMaps(AppDomain.CurrentDomain.GetAssemblies());
});
}
public IMapper GetMapper()
{
return _configuration.CreateMapper();
}
}
AutoMapperProvider
클래스 역시 DI 기반으로 동작할 것이기 때문에 생성자에서 IContainerProvider
를 주입받고 이를 사용해 MapperConfiguration
필드를 초기화한다.
MapperConfiguration
은 내부적으로 IContainerProvider.Resolve
메서드를 사용해 서비스를 빌드하게 된다. 또한, 직접 AutoMapper.Profile
인스턴스를 하나 하나 등록하지 않고 ASP.NET에서 사용하듯 자동으로 검색해 등록하도록 AddMaps
를 설정한다.
GetMapper
에서는 이렇게 구성된 MapperConfiguration
객체를 사용하여 새 매퍼 인스턴스를 반환하도록 한다.
의존성 주입
이제 주입해야 하는 코드에서(App.xaml.cs 등) 설정을 완료하면 된다.
private IMapper GetMapper(IContainerProvider containerProvider)
{
var provider = containerProvider.Resolve<IAutoMapperProvider>();
return provider.GetMapper();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IAutoMapperProvider, AutoMapperProvider>();
containerRegistry.Register(typeof(IMapper), GetMapper);
}
공급자는 싱글톤으로 구성하고, 매퍼 인스턴스는 transient로 구성하여 올바르게 작동하도록 한다.
사용
이제 원하는 곳에서 주입하여 사용할 수 있다.
public class AViewModel
{
private readonly IMapper _mapper;
public AViewModel(IMapper mapper)
{
_mapper = mapper;
}
// ...
public void AMapperUsesIMapper()
{
_mapper.Map<TypeA>(instance);
}
}
프리즘 홈페이지에서조차 둘을 혼용해 사용한다. 직접 써보니 라이브러리보단 프레임워크 개념에 가까웠다. ↩︎
댓글
댓글 쓰기