AutoMapper Kullanımı
Husamettin Elalmis
Last updated
Husamettin Elalmis
Last updated
AutoMapper Kullanımı
Merhaba arkadaşlar, bu yazıda sizlere AutoMapper kavramından bahsecedeğim.
AutoMapper Nedir?
Bir objedeki değerleri, başka bir objeye, property isimleri üzerinden verileri aktarma işini yapan 3th araca verilen isimdir AutoMapper
Nuget package olarak kurulur
AutoMapper kütüphanesini, genellikle dbden okuduğumuz Entityleri, DTO classlarına maplemek için veya tersi durumlar için kullanırız.
AutoMapper kullanmaz isek, verileri aktarma işlemini manuel uzun uzun yazarak yaparız.
Bunu pek tercih etmeyiz, çünkü Entity classımıza veya Dto classımıza yeni propertyler eklenmiş olabilir. Bunları manuel setleme işlemlerinde gözden kaçırabiliriz. Bu nedenle AutoMapper kullanarak bu tarz unutulabilecek kodlama hatalarından kaçınmayı tercih ediyoruz.
Entity / Dto / Model Nedir ?
Entity, dbdeki tablolara bire-bir karşılık gelen class yapılarına diyoruz.
Dto (Data Transfer Object), UI ile Backend arasında veri taşıma işlemini yapan class yapılarına diyoruz.
Genellikle, bir dto classını, bir entity classı ile eşleştiriyoruz.
Aksi belirtilmediği sürece, Dto yapısı ile Entity yapıları genellikle aynıdır.
Veri tabanından UI katmanına göndermek istemediğimiz propertyleri Dto classında eleminasyon ile (Dto ya eklemeyerek) yapıyoruz.
Böylece, veritabanındaki kritik dataları UI katmanına taşımamış oluyoruz.
Dto kullanmak şart değildir, ancak UI katmanı ile DB katmanı arasındaki gelen giden veriyi transform etmek istiyorsak mutlaka araya Dto classları ekliyoruz.
Bazı projelerde, veri katmanındaki veri kritik öneme sahip olmaz, bu tarz durumlarda mapleme işlemine ihtiyaç duymayız, DBdeki veriyi direkt çağırıp üzerinde değişiklik yapıp tekrar DBye geri göndermeyi tercih edebiliyoruz.
Model, genellikle İş Senaryolarına uygun UI tarafında kullanabileceğimiz, çoklu Dto kullanımıdır. Dto'lardan daha büyük hacme sahip olurlar. Birden fazla Dto ve Bunların listelerinden oluşan bir model tasarlanabilir. Bu modeli UI tarafında veya Business katmanında kullanabilmekteyiz.
Model kavramı, genellikle MVC pattern yapılarında karşımıza çıkar. Razor engine tarafından özellikle Model classlar kullanılmaktadır.
Model kavramı, tüm projelerde kullanılabilir. İş senaryosuna göre değişiklik gösterebilir.
Örnek 01 – Entity classını Dto classına maplemek
Maplemek derken, t_Personel classındaki propertylere atanmış verileri t_PersonelDto classına aktarmak anlarız.
Mapleme işleminde, aksi belirtilmediği sürece tipi ve ismi aynı olan propertyler kaynaktan hedefe doğru aktarılır.
t_Personel entity classımız olsun
t_PersonelDto dto classımız olsun
t_Personel classındaki verileri t_PersonelDto classına aktarma işlemini normalde manuel olarak şu şekilde yaparız
personelDto.Id = t_Personel.Id
personelDto.FirstName = t_Personel.FirstName
perosnelDto.LastName = t_Personel.LastName
personelDto.BirthDate = t_Personel.BirthDate
personelDto.Gender = t_Personel.Gender
bu aktarma işlemi manuel yöntemdir.
Bunu AutoMapper ile yapmak istersek, şöyle yaparız,
AutoMapper, bizden Source ve Target olmak üzere 2 adet sınıf ister. Neyi neye aktarmak istiyorsun bana şablonunu tanımla der.
AutoMapper, ilk parametre olarak Source'u, ikinci parametre olarak Target'I alır.
var personnelDto = mapper.Map<t_Personnel, t_PersonnelDto>(personnel);
şeklinde bir komut satırı ile otomatik maplame işlemini yapmış oluruz.
Bu örnekte, Dto classımızda farklı isimde bir property geçmektedir. Amacımız, personel entitysindeki FirstName'i, dto classımızdaki FName'e aktarmak ise, bunu AutoMappere nasıl olacağını söylemeliyiz, bunun şablonunu vermeliyiz, bu şablon AutoMapperin configurasyon bloğunda verilir, aşağıdaki şekildedir
x.CreateMap<t_Personnel, t_PersonnelDto>().ForMember(target => target.FName, src => src.MapFrom(s => s.FirstName + "-" + s.LastName));
Dto'daki FName değerine, personeldeki FirstName+"-"+LastName şeklinde bas diyebiliyoruz.
Bu tarz özel kolonları formüle etmek için AutoMapperin bir komutu olan MapFrom özelliğini kullanırız.
AutoMapper, DBden gelen veri listesini belirttiğimiz bir objeye mapleyebilmektedir.
Bunu yaparken bizden IQuerable türünden veri kümesi ister.
IQuerable veri kümesini, ProjectTo komutu ile mapleyebiliriz.
mapper.ProjectTo<t_PersonnelDto>(context.t_Personnel.AsQueryable());
Örnek 04 – Dto Classını Entity Classına Maplemek
Örnek 01'deki işlemin tersini şablon olarak verebiliriz, veya ReverseMap komutunu kullanabiliriz.
ReverseMap komutu AutoMapperin bir komutudur. Çift yönlü mapleme yapılabileceğini söylemiş oluyoruz.
x.CreateMap<t_Personnel, t_PersonnelDto>().ReverseMap();
Program.cs
Program.cs
using AutoMapper;
using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Linq;
namespace AutoMapperArge
{
public enum GenderEnum
{
Unknown = 0,
Male = 1,
Female = 2
}
public class t_Personnel
{
[Key]
public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime BirthDate { get; set; } public GenderEnum Gender { get; set; }
}
public class t_PersonnelDto
{
public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime BirthDate { get; set; } public GenderEnum Gender { get; set; }
}
public class t_PersonnelDto2
{
public int Id { get; set; } public string FName { get; set; } public string LastName { get; set; } public DateTime BirthDate { get; set; } public GenderEnum Gender { get; set; }
}
public class t_Customer
{
[Key]
public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime BirthDate { get; set; } public int CustomerCode { get; set; }
}
public class t_CustomerDto
{
public int Id { get; set; } public string FullName { get; set; } public int CustomerCode { get; set; }
}
public class AppDbContext : DbContext
{
public AppDbContext()
{
Database.Connection.ConnectionString = @"Data Source=DESKTOP-PBV06FI\Server2014; Initial Catalog=PhoneBookDB; Persist Security Info=True; Integrated Security=SSPI;pooling=true;";
}
public DbSet<t_Personnel> t_Personnel { get; set; }
}
class Program
{
static void Main(string[] args)
{
Console.BackgroundColor = ConsoleColor.White;
Console.ForegroundColor = ConsoleColor.Black;
Console.Clear();
// Install-Package EntityFramework // Install-Package AutoMapper -Version 10.0.0 (son sürümü 11.0.0, .NetCore için)
t_Personnel personnel = new t_Personnel();
personnel.Id = 1;
personnel.FirstName = "Hüsamettin";
personnel.LastName = "Elalmış";
personnel.BirthDate = new DateTime(1976, 03, 13);
personnel.Gender = GenderEnum.Male;
t_CustomerDto customerDto = new t_CustomerDto();
customerDto.Id = 2;
customerDto.FullName = "Hüsamettin ELALMIŞ";
customerDto.CustomerCode = 1;
// AutoMapper configurasyounu yapıyoruz var config = new MapperConfiguration(x =>
{
// ilk parametre Source, ikinci parametre Target'dır. // ReverseMap çift yönlü maplemek içindir
x.CreateMap<t_Personnel, t_PersonnelDto>().ReverseMap();
// ForMember, custom eşleştirme içindir
x.CreateMap<t_Personnel, t_PersonnelDto2>().ForMember(target => target.FName, src => src.MapFrom(s => s.FirstName + "-" + s.LastName));
x.CreateMap<t_Customer, t_CustomerDto>().ForMember(target => target.FullName, src => src.MapFrom(s => s.FirstName + "-" + s.LastName));
x.CreateMap<t_CustomerDto, t_Customer>().ForMember(target => target.FirstName, src => src.MapFrom(s => s.FullName));
});
// mapper oluşturuyoruz
IMapper mapper = config.CreateMapper();
// map işlemlerine tabi tutuyoruz var personnelDto = mapper.Map<t_Personnel, t_PersonnelDto>(personnel);
Console.WriteLine($"== Personnel entitysini PersonnelDto'suna mapledim ==");
Console.WriteLine($"{personnelDto.Id} {personnelDto.FirstName} {personnelDto.LastName} {personnelDto.Gender} {personnelDto.BirthDate}");
Console.WriteLine();
var personnelDto2 = mapper.Map<t_Personnel, t_PersonnelDto2>(personnel);
Console.WriteLine($"== Personnel entitysini PersonnelDto2'suna mapledim ==");
Console.WriteLine($"{personnelDto2.Id} {personnelDto2.FName}");
Console.WriteLine();
var customer = mapper.Map<t_CustomerDto, t_Customer>(customerDto);
Console.WriteLine($"== CustomerDto'u Customer entitysine mapledim ==");
Console.WriteLine($"{customer.Id} {customer.FirstName}");
Console.WriteLine();
// dbden gelen veri kümesini dto listesine map ediyoruz
AppDbContext context = new AppDbContext();
var querable = mapper.ProjectTo<t_PersonnelDto>(context.t_Personnel.AsQueryable()); var dtoList = querable.ToListAsync().Result;
Console.WriteLine($"== DBden t_Personnel verilerini çektim, bunları Dto listesine mapledim ==");
foreach (var item in dtoList)
{
Console.WriteLine($"{item.Id} {item.FirstName} {item.LastName} {item.Gender} {item.BirthDate}");
}
Console.WriteLine("ok");
Console.ReadLine();
}
}
}
Sonuç
Bu dokumanda AutoMapper kavramını uygulamalı görmüş olduk
Birçok projede sıkça kullanılmaktadır
Saygılarımla,
Hüsamettin ELALMIŞ – 12.06.2022
husamettin.elalmis@arksoft.com.tr
Npm Kurulumu
Örnek 02 – Entity classını Dto classına maplemek
Örnek 03 – DBden Gelen Veri Listesini Dto Listesine maplemek