Zgodnie z tym, co napisałam w poprzednim poście, dzisiaj opisuję zastosowanie w projekcie AutoMappera.
Przykład zastosowania AutoMappera
Moje wcześniejsze rozwiązanie wyglądało następująco: miałam klasę GamerMapper, a w nim 2 metody:
- MapToGamerViewModel, która z obiektu Gamer tworzyła obiekt GamerViewModel
- MapToGamerList, która z listy obiektów Gamer tworzyła listę obiektów GamerViewModel (wykorzystywała wcześniejszą metodę)
public class GamerMapper
{
public static IEnumerable<GamerViewModel> MapToGamerList(IEnumerable<Gamer> gamerList)
{
return gamerList.Select(x => MapToGamerViewModel(x)).ToList();
}
public static GamerViewModel MapToGamerViewModel(Gamer gamer)
{
if (gamer == null)
{
return null;
}
else
{
return new GamerViewModel()
{
Id = gamer.Id.ToString(),
Nick = gamer.Nick,
Name = gamer.Name,
Surname = gamer.Surname,
Email = gamer.Email,
Age = gamer.Age,
City = gamer.City,
Street = gamer.Street
};
}
}
}
Po zmianach klasa GamerMapper została przekształcona w klasę GamerProfile dziedziczącą po klasie AutoMapper.Profile. W jej kostruktorze jest zadeklarowane jedno mapowanie: z obiektu Gamer do obiektu GamerViewModel.
Wygląda to tak:
public class GamerProfile : Profile
{
public GamerProfile()
{
CreateMap<Gamer, GamerViewModel>();
}
}
Wywołanie mappera jest bardzo proste, zarówno dla listy, jak i pojedynczego obiektu:
var gamerViewModel = Mapper.Map<GamerViewModel>(gamer); var gamerViewModelList = Mapper.Map&<List<GamerViewModel>>(gamerList);
Konfiguracja AutoMappera
Tyle zmian w kodzie. Oczywiście musiałam najpierw dodać AutoMappera do mojej aplikacji. Ściągnęłam paczkę z nugeta:

i dodałam konfigurację każdego profilu w pliku Global.asax.cs
builder.RegisterType<GamerProfile>().SingleInstance();
Błąd Mapper not initialized
Już myślałam, że zadziała, ale dostałam błąd:
“Mapper not initialized. Call Initialize with appropriate configuration.”
Okazało się, że zapomniałam zainicjalizować mój mapper. Wystarczyło w pliku Global.asax.cs zdefiniować i wywołać metodę Initialize():
public static void InitializeAutoMapper()
{
Mapper.Initialize(x =>
{
x.AddProfile<GamerProfile>();
}
);
}
Po użyciu tej metody okazało się, że rejestracja typów (przedstawiona w akapicie Konfiguracja) nie jest potrzebna.
Podsumowanie
Działa!
Został mi do rozwiązania jeszcze jeden problem: mapowanie na podstawie 2 źródeł do 1 obiektu. Nie udało mi się na razie znaleźć rozwiązania, więc następny wpis będzie zapewne o tym.
PS – Link do kolejnej części dotyczącej AutoMappera znajdziecie tutaj.
2 źródła do 1 obiektu można przemapować, używając niegenerycznej metody Map: Mapper.Map(from, to) i wywołując ją wielokrotnie z różnymi źródłami i tym samym celem. Przykład pierwszy z brzegu: https://stackoverflow.com/questions/21413273/automapper-convert-from-multiple-sources
PolubieniePolubione przez 1 osoba
Update: ta metoda jak najbardziej jest generyczna, to był tylko skrót myślowy, że nie trzeba podawać parametrów typu.
PolubieniePolubienie
Dziękuję za radę!
PolubieniePolubienie
Pingback: Refactoring: AutoMapper cz. 2 – programmer-girl
Pingback: Refactoring: AutoMapper cz. 3 – programmer-girl