Wraz z nowym podejściem architektonicznym zaszła potrzba przepisywania obiektów klas domenowych na obiekty typu DTO. W celu uproszczenia sobie sprawy zastosowałem bilbiotekę AutoMapper, która będzie głównym gościem tego posta.
Jak zwierzęta?
Gdy zajdzie potrzeba przepisywania/mapowania obiektów domeny na DTO można zastosować podejście ręczne. Jako przykład wezmę oklepaną do bólu klasę User
oraz UserDto
.
W swojej aplikacji użyłem metody GetUser
, która zwraca obiekt typu UserDto
i aby to zrobić muszę recznie dokonać przepisywania właściwości.
Obiekt typu User
pobierany jest z repozytorium projektu Databoard.Core
.
Przy każdej zmianie klasy typu DTO będę musiał dokonywać zmiany w przypisywaniu wartości - co jest czasochłonne i może prowadzić do generowania błędów. Cały proces można zautomatyzować przy użyciu biblioteki AutoMapper.
Prawdopodobnie powyższy kod można byłoby mapować korzystając z mechanizmu refleksji, jednak nie jest to łatwe i nie ma sensu wyważać otwartych drzwi.
A można automatycznie!
AutoMapper mała, lekka biblioteka, która pozwala na pozbycie się powyższego kodu służącego do przepisywania wartości, a zostawia czas programiście na zajmowanie się prawdziwymi problemami :-) Napisana przez Jimmy Bogard, źródła dostępne są na GitHub wraz z wyczerpującą wiki.
Aby rozpocząć pracę z bilbioteką należy ją zainstalować korzystając z Nuget - dotnet add package AutoMapper
. W moim przypadku dodałem referencję dla dwóch projektów DataBoard.Infrastructure
oraz DataBoard.Web
dla wersji 6.0.2.
W projekcie DataBoard.Infrastructure
utworzyłem statyczną klasę AutoMapperConfig
wraz ze statyczną metodą Initialize
ze zwracanym interfejsem IMapper
, który będzie wstrzykiwany przed wywołaniem mapowania. cfg.CreateMap<User, UserDto>();
definiuje z źródło i cel mapowania.
W Databoard.Web
muszę w konfiguracji dodać services.AddSingleton(AutoMapperConfig.Initialize());
ponieważ konfiguracja jest jedna i będzie niezmieniona przez cały cykl życia aplikacji jako procesu.
Teraz można użyć biblioteki zamiast ręcznego przepisywania właściwości. Należy pamiętać o wstrzyknięciu zależności IMapper
w konstruktorze klasy, w której zdefiniowana jest metoda, w moim przypadku w klasie UserService
.
Powyżej przedstawiam najprostsze użycie AutoMappera. Pozwala ona na dużo więcej jak chociażby na mapowanie kolekcji, przypisywanie wartości domyślnych, czy też omijanie właściwości przy mapowaniu, po więcej odsyłam do wiki.