AutoMapper – przydatna biblioteka

AutoMapperW celu łatwiejszego zrozumienia co to jest AutoMapper jak on działa posłużę się przykładem. Ale najpierw trzy zdania wstępu: AutoMapper jest jedną z najczęściej używanych bibliotek. AutoMapper jest prostą biblioteką zbudowaną do rozwiązywania złożonych problemów polegających na mapowaniu jednego obiektu na drugi. Pisanie maperów jest raczej nużącą i nudną czynnością, więc dlaczego nie użyć narzędzia, które zrobi to za nas?

AutoMapper – przykład użycia

Wyobraźmy sobie, że Zbigniew chce sprzedać samochód. Stwórzmy w tym celu dwie klasy: Samochod i Osoba.

class Osoba
{
	public string Imie { get; set; }
	public string Nazwisko { get; set; }
	public string Miast { get; set; }
	public string PESEL { get; set; }
	public Samochod Samochod { get; set; }

	public Osoba(string imie, string nazwisko, string miast, string pesel, Samochod samochod)
	{
		Imie = imie;
		Nazwisko = nazwisko;
		Miasto = miast;
		PESEL = pesel;
		Samochod = samochod;
	}


class Samochod
{
	public string Marka { get; set; }

	public Samochod(string marka)
	{
		Marka = marka;
	}
}

W programie mamy również klasę Ogloszenie. Na podstawie klasy Ogloszenie będą wyświetlane informacje dla potencjalnego kupującego: kto sprzedaje i jaki samochód chce sprzedać.

class Ogloszenie
{
        public string Imie { get; set; }
        public string Nazwisko { get; set; }
        public string SamochodNaSprzedasz { get; set; }

        public Ogloszenie(Osoba osobaSprzedajaca)
        {
            Imie = osobaSprzedajaca.Imie;
            Nazwisko = osobaSprzedajaca.Nazwisko;
            SamochodNaSprzedasz = osobaSprzedajaca.Samochod.Marka;
        }

        public string Wyswietl()
        {
            return string.Format("{0}, {1} sprzedaje {2}", Imie, Nazwisko, SamochodNaSprzedasz);
        }
}

No to teraz zobaczmy jak nasz program działa:

static void Main(string[] args)
{   
	var samochod = new Samochod("Fiat 126p");
	var zbigniew = new Osoba("Zbigniew", "Kowalski", "88111243345", samochod);
	var ogloszenie = new Ogloszenie(zbigniew);
	Console.WriteLine(ogloszenie.Wyswietl());
	Console.ReadLine();
}

Zbigniew Kowalski sprzedaje Fiat 126p

Bardzo ładnie, ale jak osoba, która chce kupić samochód ma się skontaktować ze Zbigniewem? Trzeba dodać nową właściwość.

class Osoba
{
	...
	public string Telefon { get; set; }
	public Osoba(string imie, string nazwisko, string pesel, Samochod samochod, string telefon)
	{
		...
		Telefon = telefon;
	}
}

class Ogloszenie
{
	...
	public string Telefon { get; set; }

	public Ogloszenie(Osoba osobaSprzedajaca)
	{
		...
		Telefon = osobaSprzedajaca.Telefon;
	}
	
	public string Wyswietl()
	{
		return string.Format("{0}, {1} sprzedaje {2}. Kontakt: {3}", Imie, Nazwisko, SamochodNaSprzedasz, Telefon);
	}
}

Sprawdźmy jak działa program:

static void Main(string[] args)
{   
	var samochod = new Samochod("Fiat 126p");
	var zbigniew = new Osoba("Zbigniew", "Kowalski", "88111243345", samochod, "550444333");
	var ogloszenie = new Ogloszenie(zbigniew);
	Console.WriteLine(ogloszenie.Wyswietl());
	Console.ReadLine();
}

Zbigniew Kowalski sprzedaje Fiat 126p. Kontakt: 550444333

W sumie przydałoby się jeszcze dodać informacje do ogłoszenia w jakiej miejscowości te auto będzie sprzedawane. Znowu trzeba byłoby dopisać nową linijkę w konstruktorze ogłoszenia. A co jakby trzeba było przekopiować z jednej klasy do drugiej 30 różnych właściwości? Ręcznie pisać 30 linijek kodu? W tym przypadku przychodzi nam z pomocą biblioteka AutoMapper! Sprawdźmy w naszym przykładzie jak łatwo można przy pomocy AutoMappera przekopiować wartości z jednego obiektu do drugiego.

class Program
{
	static void Main(string[] args)
	{   
		var samochod = new Samochod(Color.Red, "Fiat 126p", 1986);
		var zbigniew = new Osoba("Zbigniew", "Kowalski", "88111243345", samochod, "550444333");
		AutoMapper.Mapper.CreateMap<Osoba, Ogloszenie>();
		var ogloszenie = AutoMapper.Mapper.Map<Ogloszenie>(zbigniew);
		Console.WriteLine(ogloszenie.Wyswietl());
		Console.ReadLine();
	}
}

Co otrzymujemy w rezultacie?

An unhandled exception of type ‚AutoMapper.AutoMapperMappingException’ occurred in AutoMapper.dll

Dlaczego? AutoMapper tworzy obiekt Ogloszenie przy użyciu pustego (domyślnego) konstruktora. Więc albo dodajmy do kodu pusty konstruktor Ogloszenia albo wyrzucamy konstruktor public Ogloszenie(Osoba osobaSprzedajaca). Ja wyrzucam. Skompilujmy jeszcze raz.

Zbigniew Kowalski sprzedaje . Kontakt: 550444333

AutoMapper kopiuje wartości z jednego obiektu do drugiego jeżeli nazwy właściwości są takie same. MarkaSamochoduNaSprzedasz nie została skopiowana, ponieważ klasa Osoba nie ma pola która ma taką samą nazwę. Spokojnie. AutoMapper przekopiuje odpowiednie wartości jak mu powiem jak to ma zrobić.

static void Main(string[] args)
{   
	var samochod = new Samochod(Color.Red, "Fiat 126p", 1986);
	var zbigniew = new Osoba("Zbigniew", "Kowalski", "88111243345", samochod, "550444333");
	AutoMapper.Mapper.CreateMap<Osoba, Ogloszenie>()
		.ForMember(oglo => oglo.SamochodNaSprzedasz,
				   wybierz => wybierz.MapFrom(osoba => osoba.Samochod.Marka));
	var ogloszenie = AutoMapper.Mapper.Map<Ogloszenie>(zbigniew);
	Console.WriteLine(ogloszenie.Wyswietl());
	Console.ReadLine();
}

Zbigniew Kowalski sprzedaje Fiat 126p. Kontakt: 550444333

AutoMapper ma na prawdę szeroki wachlarz możliwości. Polecam się z nim zapoznać.

AutoMapper – linki

Strona projektu
Wiki projektu (ang)
Cpratt (ang) – przykład
AltcontrolDelete (pl) – przykład
DariuszTarczynski (pl) – przykład
DevTrends (ang) – kiedy nie używać AutoMappera

Leave a Comment

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *