Giriş

Elle yazılan kodla yapılan DTO ↔ Entity dönüşümleri, boilerplate ve bakım zorluğu getirir.
AutoMapper, Profile sınıflarıyla bu dönüşümleri dekleratif, test edilebilir ve bakımı kolay hale getirir. Bu rehberde:

  1. Kurulum & Entegrasyon
  2. Profile Tasarımı & Map Ayarları
  3. ReverseMap & ForMember Derinlikleri
  4. Nested Obje ve Koleksiyon Dönüşümleri
  5. Profil Doğrulama & Test Stratejileri
  6. Performans Optimizasyonları
  7. Yaygın Hatalar & Çözümleri

şeklinde ilerleyeceğiz.

1. Kurulum & Entegrasyon

  • Assembly Tarama: Tüm profilleri otomatik yükler.
dotnet add package AutoMapper.Extensions.Microsoft.DependencyInjection
// Program.cs
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
  • Manuel Seçim:
builder.Services.AddAutoMapper(cfg => {
  cfg.AddProfile<ProductProfile>();
});

2. Profile Tasarımı & Map Ayarları

public class ProductProfile : Profile
{
    public ProductProfile()
    {
        CreateMap<Product, ProductDto>()
            .ForMember(d => d.DisplayName,
                       o => o.MapFrom(s => $"{s.Name} ({s.Code})"))
            .ForMember(d => d.PriceFormatted,
                       o => o.MapFrom(s => s.Price.ToString("C2")))
            .ForAllOtherMembers(o => o.Ignore());
    }
}
  • ForMember: Alan bazlı dönüşüm
  • MapFrom: Karmaşık ifade
  • Ignore: Fazla veri atlama

3. ReverseMap & ForMember Derinlikleri

CreateMap<ProductDto, Product>()
    .ReverseMap()
    .ForMember(src => src.CreatedAt, opt => opt.Ignore())
    .ForAllMembers(opt => opt.Condition((src, _, member) => member != null));
  • ReverseMap() tek profille çift yön
  • Condition null gelen alanları atlar

3.1. Örnek: Null Güncelleme

CreateMap<UserDto, User>()
    .ForAllMembers(opt =>
        opt.Condition((src, _, srcMember) => srcMember != null));

PATCH senaryoları için idealdir.

4. Nested Obje ve Koleksiyon Dönüşümleri

public class OrderProfile : Profile
{
    public OrderProfile()
    {
        CreateMap<Order, OrderDto>()
            .ForMember(d => d.Customer, o => o.MapFrom(s => s.User))
            .ForMember(d => d.Items, o => o.MapFrom(s => s.LineItems));
    }
}
var dtos = _context.Orders
    .Include(o => o.Items)
    .ProjectTo<OrderDto>(_mapper.ConfigurationProvider)
    .ToList();
  • Koleksiyon dönüşümleri ProjectTo ile SQL tarafında

5. Profil Doğrulama & Test Stratejileri

var config = new MapperConfiguration(cfg => {
    cfg.AddProfile<ProductProfile>();
    cfg.AddProfile<OrderProfile>();
});
config.AssertConfigurationIsValid();
[Fact]
public void AutoMapper_Configuration_IsValid()
{
    var config = new MapperConfiguration(cfg => cfg.AddMaps(typeof(Startup).Assembly));
    config.AssertConfigurationIsValid();
}
  • CI’da her PR’da çalıştırmak kaliteyi garantiler.

6. Performans Optimizasyonları

  • Singleton IMapper: Tek kez oluşturun.
  • ProjectTo: Büyük veri setlerinde kullanın.
  • Basit MapFrom: EF Core translate edilemiyen ifadelerden kaçının.

7. Yaygın Hatalar & Çözümleri

Hata Mesajı Çözüm
Missing map from X to Y Profil eklememişsiniz veya assembly taraması eksik
Expression could not be translated to SQL MapFrom içinde karmaşık kodlar yerine custom resolver tercih edin
Döngüsel referans oluşturma .MaxDepth(2) ve .PreserveReferences() kullanın

By tanju.bozok

Software Architect, Developer, and Entrepreneur

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir