Asp.NET Core’da AutoMapper Kullanımı
Merhaba,
Bu içeriğimizde Asp.NET Core uygulamalarında, ViewModel nesnelerinin modellediği gerçekci model entityleri ile eşleştirilmesini dinamik bir şekilde sağlayan AutoMapper kütüphanesinin entegrasyonunu ve kullanımını inceleyeceğiz.
Makalemize ilk olarak hiç bilmeyenler için Viewmodel nesnesinin ne olduğunu açıklayarak başlayalım;
Viewmodel Nedir?
Viewmodel nesneleri, temelde iki farklı senaryoya karşı sorumluluk üstlenen ve biz geliştiricilerin işini kolaylaştıran operasyonel nesnelerdir.
- 1. Senaryo
OOP yapılanmasında bir modelin kullanıcıyla etkileşimi neticesinde kullanılan/doldurulan memberlarını temsil eden ve süreçte ilgili model yerine kullanılan/taşınan/transfer edilen/post edilen vs. bir nesnedir.Örnek olarak hesap girişi için kullanıcı adı ve şifre ile yapılan bir post işleminde aşağıdaki gibi rol üstlenmektedir.
Gerçek model(entity);public class Personel { public int Id { get; set; } public string Adi { get; set; } public string Soyadi { get; set; } public string KullaniciAdi { get; set; } public string Sifre { get; set; } virtual public ICollection<Musteri> Musteriler { get; set; } virtual public ICollection<Satis> Satislar { get; set; } }
Viewmodel;
public class VMPersonel { public string KullaniciAdi { get; set; } public string Sifre { get; set; } }
Bu şekilde bir senaryoda post edilen nesneyi direkt olarak gerçek model/entity ile karşılarsak ilgili propertyler dışında konuyla alakasız memberlar varsayılan değerleriyle gelecektirler. Dolayısıyla bu çokta kullanışlı bir yapılanma olmayacaktır. İşte burada, post neticesinde gelen veriyi direkt değersel muhattabı olan ViewModel nesnesi ile karşılayarak lüzumsuz propertylerden arındırmış ve kullanım açısından da kolaylık sağlamış olmaktayız.
- 2. Senaryo
Birden fazla modele ihtiyaç duyulan durumlarda tek bir nesne üzerinden bu modelleri birleştirme görevi gören nesnedir.Örnek olarak aşağıdaki yapılanmayı inceleyiniz.
Gerçek model;public class Satis { public int Id { get; set; } public int PersonelId { get; set; } public string SatisNo { get; set; } virtual public Personel Personel { get; set; } }
Gerçek model;
public class Musteri { public int Id { get; set; } public int PersonelId { get; set; } public string Adi { get; set; } public string Sirketi { get; set; } virtual public Personel Personel { get; set; } }
Viewmodel;
public class VMSatis_Musteri { public Satis Satis { get; set; } public Musteri Musteri { get; set; } }
View;
@using AutoMapperProjectExample.Models.ViewModels @model VMSatis_Musteri @using (Html.BeginForm("Create", "Home", FormMethod.Post)) { @Html.TextBoxFor(p => p.Satis.SatisNo)<br /> @Html.TextBoxFor(p => p.Musteri.Sirketi)<br /> <button>Gönder</button> }
Yukarıdaki örnekten de görüldüğü üzere “Satis” ve “Musteri” nesnelerini “VMSatis_Musteri” isimli ViewModel ile tek bir nesnede birleştirmiş ve bu şekilde organize etmiş bulunmaktayız.
Görüldüğü üzere ViewModel nesneleri, bu şekilde iki farklı senaryoya göre sorumluluk üstlenen model destekçisi nesnelerimizdir.
Ayriyetten ViewModel nesneleri;
- View sayfalarında verileri tutmak için,
- Data Annotations ile Validations kurallarını belirlemek için,
- Static verileri/değerleri tutan ihtiyaca dönük nesneleri kullanabilmek için
vs. amaçlıda kullanılır.
AutoMapper Kütüphanesi Ne İşe Yarar?
ViewModel nesnesinin 1. senaryodaki sorumluluğuna karşı gerçek model ile viewmodel arasındaki eşleşmeleri otomatik bir şekilde sağlayabilmek için kullanılan bir kütüphanedir.
Şöyle ki, bir personelin sadece ad ve soyad bilgilerinden bir kayıt oluşturacaksak eğer ilgili verilerle eşleşecek bir viewmodel tasarlayarak post neticesinde gelen datayı bu viewmodel ile karşılayabiliriz. Lakin context üzerinden gerçek entity ile temas kurulabileceğinden dolayı viewmodelde ki verileri gerçek modele yani entitye aktarmamız gerekmektedir. İşte bu işlemi AutoMapper bizler yerine otomatik bir şekilde gerçekleştirmektedir.
Yukarıdaki ekran görüntüsünde viewmodel’de ki verileri manuel bir şekilde entitye aktarmış bulunmaktayız. Günün sonunda bu işlemi otomatik bir şekilde yapacak olan AutoMapper nesnesine bırakacağız.
AutoMapper Entegrasyonu
AutoMapper kütüphanesini aşağıdaki kod aracılığıyla projeye entegre edebilirsiniz;
Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection
Kurulumu
Kütüphane entegrasyonundan sonra uygulamaya “Startup.cs” dosyasındaki “ConfigureServices” metodu içerisinden AutoMapper kütüphanesini servis olarak ekliyoruz.
public void ConfigureServices(IServiceCollection services) { services.AddAutoMapper(); }
Kullanımı
AutoMapper kütüphanesini kullanabilmek için gerçek modeller(entity) ile oluşturulan viewmodeller arasındaki ilişki belirtilmelidir. Yani, hangi model hani viewmodelle eşleşecektir…
Eşleşme için AutoMapper kütüphanesinin “Profile” sınıfı kullanılmaktadır. Tüm eşleşme profillerini bu sınıf aracılığıyla gerçekleştirmekte ve uygulamaya bildirmekteyiz.
Örnek için aşağıdaki model ve viewmodelleri oluşturalım.
Gerçek modeller;
public class Musteri { public int Id { get; set; } public int PersonelId { get; set; } public string Adi { get; set; } public string Sirketi { get; set; } virtual public Personel Personel { get; set; } }
public class Personel { public int Id { get; set; } public string Adi { get; set; } public string Soyadi { get; set; } public string KullaniciAdi { get; set; } public string Sifre { get; set; } virtual public ICollection<Musteri> Musteriler { get; set; } virtual public ICollection<Satis> Satislar { get; set; } }
public class Satis { public int Id { get; set; } public int PersonelId { get; set; } public string SatisNo { get; set; } virtual public Personel Personel { get; set; } }
ViewModeller;
public class VMMusteri { public string Adi { get; set; } public string Sirketi { get; set; } }
public class VMPersonel { public string Adi { get; set; } public string Soyadi { get; set; } }
public class VMSatis { public string SatisNo { get; set; } }
“Profile” sınıfımız;
public class MappingProfile : Profile { public MappingProfile() { CreateMap<Personel, VMPersonel>(); CreateMap<VMPersonel, Personel>(); CreateMap<Musteri, VMMusteri>(); CreateMap<VMMusteri, Musteri>(); CreateMap<Satis, VMSatis>(); CreateMap<VMSatis, Satis>(); } }
Yukarıdaki kod bloğuna dikkat ederseniz eğer “Profile” abstract sınıfından türettiğimiz “MappingProfile” isimli sınıfımız bizim için eşleştirme profillerini barındıracak sorumluluğu üstlenmektedir. İşlemleri kolaylık olması açısından ilgili sınıfın constructerında gerçekleştirmeyiz. “Profile” sınıfından gelen “CreateMap” metodu aracılığıyla eşleştirmeler yapılmaktadır. Burada özellikle dikkatinizi çekmek istediğim husus, her eşleştirmenin birde simetriğini sağlayarak tersine bir çevriminde söz konusu olacağı durumlarıda hesaba katmaktayız.
Kullanım;
Yukarıdaki ekran görüntüsünü incelerseniz eğer AutoMapper, Assembly’de ki “Profile” nesnesini bulmakta ve eşleştirmeler neticesinde arka planda reflection ile memberları check ederek aralarında verilsel transferi sağlamaktadır. Dolayısıyla bizleri ekstradan bir maliyetten kurtarmakta ve hızımıza hız katmaktadır. “VMPersonel” olarak gelen nesneyi AutoMapper kütüphanesinin nimetlerinden olan “IMapper” sınıfını kullanarak “Personel” sınıfına Map(eşleştirme) etmekteyiz. Bu durum diğer modeller ve viewmodeller içinde geçerliliğini koruyacaktır. Artık gerisini sizlerin deneyine bırakıyorum…
İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…
Merhaba,
Automapper ile farklı propertyleri eşleştirmek istiyorsanız eğer aşağıdaki örneği inceleyebilirsiniz.
Bu şekilde kodu geliştirerek farklı isimdeki propertylerin hangileriyle eşleşeceğini belirtebilirsiniz…
Sevgiler…
Merhaba,
Authomapper ile bir metot dönüş değeri ile property’i eşleştirmek istiyorsanız eğer aşağıdaki örneği inceleyebilirsiniz.
Ana modeldeki metot ismiyle Dto’da ki property ismi aynı olduğu taktirde otomatik ilgili metodun değerini property’e verecektir. Burada modeldeki fonksiyonun adı aşağıdaki gibi ‘Get’ ön ekiyle de başlayabilir.
Bu şekilde de ilgili metotla property sorunsuz eşleştirilmiş olacaktır.
Eğer ki metot ismiyle eşleştirileceği property ismi farklıysa bunun aşağıdaki örneği inceleyiniz.
Böylece ‘Urun’ modelindeki Ozet metodu ‘UrunDto’ modelindeki ‘UrunOzeti’ propertysiyle eşleştirilmiştir.
Kolay gelsin…
Sevgiler…
Merhaba,
Flattening
Düzleştirmek, yassılaştırmak anlamına gelen bu terim complex bir property’i sadece basit propertyler barındıran bir türe dönüştürmeyi ifade eder.
Örneğin;
Yukarıda görüldüğü üzere ‘Musteri’ sınıfı içerisindeki ‘Banka’ propertysi ‘Banka’ türünden bir nesneyi temsil etmektedir. Yani complex bir propertydir.
Bu eşleştirme neticesinde ‘Musteri’ sınıfı içerisindeki ‘Banka’ propertysinin ‘Bakiye’ bilgisi ‘MusteriDto’nun ‘BankaBakiye’ propertysine otomatik eşleştirilecektir. Buradaki formatın ‘[ComplexClassName][PropertyName]‘ olduğuna dikkatinizi çekerim. Eğer ki ‘MusteriDto’nun ‘BankaBakiye’ propertysinin ismi bu formatta olmasaydı aşağıdaki gibi çalışılması gerekecekti.
Yukarıda görüldüğü üzere ‘MusteriDto’da ki ‘Bakiye’ propertysini direkt olarak ‘Musteri’ içerisindeki ‘Banka’ propertysinin ‘Bakiye’ bilgisiyle eşleştirebilmek için;
şeklinde çalışılması yeterlidir.
Merhaba,
IncludeMembers
Yukarıdaki gibi complex bir property’i sadece basit propertyler barındıran bir türe dönüştürürken birebir aynı property isimlerinin kullanıldığı durumlarda otomatik eşleştirme sağlanabilmesi için ‘IncludeMembers’ kullanılabilir.
Bu kullanım ‘MusteriDto’ sınıfındaki ‘Bakiye’ propertysi ile ‘Musteri’ sınıfındaki ‘Banka’ türünden propertynin ‘Bakiye’ verisini otomatik eşleştirmektedir. Haliyle ekstradan ForMember ile bir eşleştirmeye yapmaya gerek kalmamaktadır.
Sevgiler…
Merhaba,
Projection
Bir modeldeki property bilgisinin parçalanarak birden fazla property ile eşleştirilmesine Projection denmektedir.
Örneğin;
modelleri uygun olacak şekilde eşleştirilmek istenirse eğer
şeklinde çalışılması yeterli olacaktır.
Kolay gelsin.
Teşekkür ederim gencay bey, .net core’a başlayalı bir hafta oldu. Yazılarınızdan baya yararlandım. Elinize sağlık.
Emeklerinize sağlık. Henüz hazmetmeye çalışsam da çok faydalı bir paylaşım olduğunu anlıyorum. Teşekkürler.
Elinize emeğinize sağlık çok faydalı oldu.
hocam claim listesini automapper kullanarak aşağıdaki gibi bir clasa cast ediyorum
fakat sadece ilk alan mapleniyor ,USERNAME digeri boş geliyor. Neden olabilir.
–Class
–Profile
Teşekkürler hocam gayet açıklayıcı olmuş.
Ayriyetten değil hocam ayrıyeten.
Evet, katılıyorum 🙂
Hocam, bende entitye ait alanlar dolu gelmiyor dto’ya makalenizdeki gibi yaptım.
Hocam merhaba,
Bir modelde string iken diğer modelde Keyvalue(Key,Value şeklinde bir tip) olduığu senaryoda istiyorum ki heddef alandaki stringe Keyvalue alanının Valuesini atasın. tüm propertylerinde geçerli olacak şekilde nasıl yapılabilir bu.
Selam,
ViewModel 2. senaryo viewmodel kurallarına aykırı geldi bana bilmiyorum belki yanlış düşünüyorum.
Oluşturdugunuz viewmodel içerisine “satis” ve “musteri” nesnelerini eklediniz yani viewmodel içerisinde gerçek model nesnelerini dahil ettiniz dolayısıyla dışardan temiz görünen ama içerde kirli, gereksiz bilgi barındırılmış oldu ve buda veri açığına da yol açmış oldu.Sanki viewmodel içerisinde gerçek model tanımlamalarını yapmasan daha iyi olacaktır, hiç bir viewmodel gerçek model(entity) içerisinde barındırmamalı.