VeloxMapper.Core 4.1.1

dotnet add package VeloxMapper.Core --version 4.1.1
                    
NuGet\Install-Package VeloxMapper.Core -Version 4.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="VeloxMapper.Core" Version="4.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="VeloxMapper.Core" Version="4.1.1" />
                    
Directory.Packages.props
<PackageReference Include="VeloxMapper.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add VeloxMapper.Core --version 4.1.1
                    
#r "nuget: VeloxMapper.Core, 4.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package VeloxMapper.Core@4.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=VeloxMapper.Core&version=4.1.1
                    
Install as a Cake Addin
#tool nuget:?package=VeloxMapper.Core&version=4.1.1
                    
Install as a Cake Tool

VeloxMapper

VeloxMapper, modern .NET platformları (.NET 8.0, .NET 9.0 ve .NET 10.0) için tasarlanmış; performans, tip güvenliği ve gözlemlenebilirliği (observability) önceliklendiren, deterministik ve fail-fast (erken hata) tabanlı hibrit bir nesne eşleştirme (object mapping) kütüphanesidir.

Bu proje, AutoMapper gibi geleneksel kütüphanelerin sunduğu dinamik ve bazen "sürprizli" (implicit/black-box) davranışlar yerine; katı kuralları, derleme zamanı güvencelerini ve startup doğrulamasını merkeze alır. VeloxMapper ile yazılan haritalama kuralları asla belirsiz kalmaz; hata varsa uygulama ayağa kalkarken (fail-fast) tespit edilir.


🚀 Neden VeloxMapper?

  • Fail-Fast (Startup Validation): Hatalı veya eksik eşleştirmeler, uygulama ayağa kalkarken yapılan doğrulama (AssertConfigurationIsValid) ile hemen yakalanır. Üretim ortamında (production) beklenmedik çalışma zamanı hataları yaşamazsınız.
  • Çift Katmanlı (Hibrit) Motor:
    • Layer 1 (Source Generator): [VeloxMap] niteliğiyle işaretlenen sınıflar için derleme zamanında NativeAOT uyumlu, reflection içermeyen, allocation-free saf C# kodları üretir.
    • Layer 2 (Expression Tree): Dinamik senaryolarda haritalama planlarını çalışma zamanında bellekte bir kez derleyerek strongly-typed delegateler (Func<TSource, TDest>) oluşturur ve önbelleğe alır.
  • Gözlemlenebilirlik (Observability): Haritalama planlarının ne yaptığını ve hangi özelliğin hangi yöntemle eşleştiğini gösteren JSON/Text raporları üretebilir. Eşleştirme kurallarının kazara bozulmasını önlemek için CI/CD snapshot testleri ile SHA-256 doğrulamasını destekler.
  • AutoMapper Birebir Geçiş Desteği: VeloxProfile, CreateMap<A, B>(), ForMember, MapFrom, Ignore ve otomatik profile scanning (assembly tarama) yetenekleri sayesinde AutoMapper kullanan projelerinizi minimum eforla VeloxMapper'a geçirebilirsiniz.

📦 Kurulum

VeloxMapper, analyzer bileşeni entegre edilmiş tek bir paket olarak kurulur. .NET 8.0, .NET 9.0 ve .NET 10.0 platformlarını yerel (multi-targeting) olarak destekler. Source Generator arka planda otomatik devreye girer.

dotnet add package VeloxMapper

🛠️ Temel Yapılandırma ve Profil Sistemi

1. Haritalama Profili Tanımlama

VeloxProfile sınıfından türeyen bir profil oluşturun ve eşleştirmelerinizi yapıcı metot (constructor) içerisinde tanımlayın:

using VeloxMapper.Configuration;

/// <summary>
/// Kullanıcı haritalama kurallarını barındıran profil sınıfı.
/// </summary>
public class UserMappingProfile : VeloxProfile
{
    /// <summary>
    /// Profil yapılandırmasını başlatan yapıcı metot.
    /// </summary>
    public UserMappingProfile()
    {
        // Temel eşleştirme (Property isimleri case-insensitive olarak otomatik eşleşir)
        CreateMap<AddressSource, AddressDest>();

        // Custom kurallar içeren eşleştirme
        CreateMap<UserSource, UserDest>()
            .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}"))
            .ForMember(dest => dest.SecretToken, opt => opt.Ignore());

        // Otomatik Ters Yön Eşleştirme (ReverseMap)
        CreateMap<CompatibilitySource, CompatibilityDest>().ReverseMap();
    }
}

2. Dependency Injection (DI) ve Assembly Scanning

ASP.NET Core uygulamalarınızda haritaları otomatik taratarak kaydetmek için AddVeloxMapper extension metodunu kullanabilirsiniz.

// Program.cs
using VeloxMapper.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// VeloxMapper servis kaydı ve assembly tarama
builder.Services.AddVeloxMapper(cfg =>
{
    // Belirtilen Assembly içindeki tüm VeloxProfile sınıflarını otomatik tarar ve yükler
    cfg.AddProfilesFromAssembly(typeof(UserMappingProfile).Assembly);

    // Patch haritalama davranışında kaynak null ise hedef değerin korunmasını ayarlar (opsiyonel)
    cfg.PatchMapping.IgnoreNullValues = true;
});

⚡ Gelişmiş Haritalama Yetenekleri

1. Düzleştirme (Flattening) ve Çözme

Kaynak nesnedeki iç içe geçmiş (nested) nesnelerin property'lerini hedefteki düz (flat) property'lere otomatik olarak eşler:

  • Kural: Source.Address.City ➡️ Dest.AddressCity (veya Prefix/Convention kurallarımıza göre Address_City)
public class Address 
{ 
    public string City { get; set; } = string.Empty;
}

public class CustomerSource 
{ 
    public Address Address { get; set; } = new();
}

public class CustomerDest 
{ 
    public string AddressCity { get; set; } = string.Empty;
}

// Profilde sadece CreateMap tanımlanması yeterlidir. İç içe özellik otomatik çözümlenir:
// CreateMap<CustomerSource, CustomerDest>();

2. Koleksiyon Haritalama ve Null Yönetimi

List<T>, T[], IEnumerable<T>, ICollection<T>, IList<T> ve HashSet<T> tipleri arasında derinlemesine eleman dönüşümü yapar.

  • AllowNullCollections (Varsayılan: false):
    • false ise: Kaynak koleksiyon null ise, hedefte boş bir koleksiyon (boş array, boş liste, boş HashSet) oluşturulur.
    • true ise: Kaynak koleksiyon null ise, hedef koleksiyon da null bırakılır.
var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<SourceModel, DestModel>();
    
    // Null kaynak koleksiyonların hedefte null olarak kalmasını sağlar
    cfg.AllowNullCollections = true; 
});

3. Null İkame Değeri (NullSubstitute)

Kaynak özellik null olduğunda hedefe atanacak varsayılan bir alternatif değer tanımlayabilirsiniz:

CreateMap<UserSource, UserDest>()
    .ForMember(dest => dest.Bio, opt => opt.NullSubstitute("Kullanıcı henüz biyografi eklemedi."));

4. Koşullu Eşleme (Condition & PreCondition)

  • PreCondition: Atama adımları başlamadan önce tüm kaynağı kontrol eder. Koşul sağlanmazsa ilgili hedef alan atanmaz.
  • Condition: Çözümlenmiş değer üzerinden kontrol yapar.
CreateMap<UserSource, UserDest>()
    // Sadece yaş 18'den büyükse atamayı gerçekleştir (PreCondition)
    .ForMember(dest => dest.AdultData, opt => opt.PreCondition(src => src.Age >= 18))
    // Sadece çözümlenen değer null değilse hedef alana yaz (Condition)
    .ForMember(dest => dest.Status, opt => opt.Condition((src, dest, val) => val != null));

5. Özel Değer Çözümleyiciler (Resolvers) ve Dönüştürücüler (Converters)

VeloxMapper, AutoMapper'da bulunan tüm resolver ve converter yapılarını modern ve bağımlılık enjeksiyonuna (DI) uyumlu hale getirilmiş arayüzlerle destekler.

A. IVeloxValueResolver (DI Destekli Değer Çözümleyici)

Kaynak nesnenin tamamını kullanarak hedefteki tek bir alanı hesaplamak için kullanılır. Sınıf kurucusunda (constructor) DI bağımlılıkları alabilir.

using VeloxMapper.Abstractions;
using VeloxMapper.Execution;

/// <summary>
/// Kullanıcı profil görseli için HTTP bağlamını kullanarak tam URL üretir.
/// </summary>
public class CustomImageUrlResolver : IVeloxValueResolver<AppUser, UserDto, string?>
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public CustomImageUrlResolver(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public string? Resolve(AppUser source, UserDto destination, VeloxResolutionContext context)
    {
        var scheme = _httpContextAccessor.HttpContext?.Request.Scheme ?? "https";
        var host = _httpContextAccessor.HttpContext?.Request.Host.Value ?? "localhost";
        return $"{scheme}://{host}/images/{source.ImageName}";
    }
}

// Profil Kaydı:
CreateMap<AppUser, UserDto>()
    .ForMember(dest => dest.ImageUrl, opt => opt.MapFrom<CustomImageUrlResolver>());
B. IVeloxMemberValueResolver (Kaynak Özellik Bağımlı Çözümleyici)

Kaynak nesnedeki belirli bir özellik değerini girdi olarak alıp işleyerek hedef alanı çözümlemek için kullanılır.

using VeloxMapper.Abstractions;
using VeloxMapper.Execution;

/// <summary>
/// Fiyat ve indirim hesaplaması yapan özellik seviyesinde çözümleyici.
/// </summary>
public class DiscountCalculator : IVeloxMemberValueResolver<Order, OrderDto, decimal, decimal>
{
    public decimal Resolve(Order source, OrderDto destination, decimal sourceMember, decimal destMember, VeloxResolutionContext context)
    {
        // Kaynak özellikten gelen fiyatı %10 indirimle hesaplar
        return sourceMember * 0.90m; 
    }
}

// Profil Kaydı (Price özelliğini DiscountedPrice alanına map ederken DiscountCalculator kullan):
CreateMap<Order, OrderDto>()
    .ForMember(dest => dest.DiscountedPrice, opt => opt.MapFrom<DiscountCalculator, decimal>(src => src.Price));
C. IVeloxValueConverter (Özellik Seviyesi Değer Dönüştürücü)

Özellik seviyesinde tip dönüşümleri veya veri maskeleme gibi işlemler için tekrar kullanılabilir dönüştürücüler tanımlamanızı sağlar.

using VeloxMapper.Abstractions;
using VeloxMapper.Execution;

/// <summary>
/// Kredi kartı numarasını maskeleyerek string'e dönüştürür.
/// </summary>
public class CardMaskConverter : IVeloxValueConverter<long, string>
{
    public string Convert(long sourceMember, VeloxResolutionContext context)
    {
        var cardStr = sourceMember.ToString();
        if (cardStr.Length < 12) return "****";
        return $"{cardStr[..4]} **** **** {cardStr[^4..]}";
    }
}

// Profil Kaydı:
CreateMap<PaymentSource, PaymentDest>()
    .ForMember(dest => dest.MaskedCardNumber, opt => opt.ConvertUsing<CardMaskConverter, long>(src => src.RawCardNumber));
D. IVeloxTypeConverter (Tür Seviyesi Özel Dönüştürücü)

Otomatik eşleştirme kurallarının tamamen yerine geçerek, bir kaynaktan hedefe dönüşümü bütünsel olarak ele alır.

using VeloxMapper.Abstractions;

/// <summary>
/// XML veya dış kaynaktan gelen karmaşık dizeyi DateTime nesnesine dönüştürür.
/// </summary>
public class CustomDateTimeConverter : IVeloxTypeConverter<string, DateTime>
{
    public DateTime Convert(string? source)
    {
        if (string.IsNullOrEmpty(source)) return DateTime.MinValue;
        return DateTime.ParseExact(source, "yyyyMMddHHmmss", null);
    }
}

// Profil Kaydı:
CreateMap<string, DateTime>().ConvertUsing(new CustomDateTimeConverter());

6. Yaşam Döngüsü Kancaları (BeforeMap / AfterMap)

Eşleştirme işleminden hemen önce veya sonra çalıştırılacak mantıksal eylemleri (Inline delege veya DI bağımlı IVeloxMappingAction sınıfı) tanımlayabilirsiniz:

using VeloxMapper.Abstractions;
using VeloxMapper.Execution;

/// <summary>
/// Haritalama sonrasında hedef nesneye log veya audit bilgilerini basan eylem sınıfı.
/// </summary>
public class AuditLogAction : IVeloxMappingAction<UserSource, UserDest>
{
    private readonly ILogger<AuditLogAction> _logger;

    public AuditLogAction(ILogger<AuditLogAction> logger)
    {
        _logger = logger;
    }

    public void Process(UserSource source, UserDest destination, VeloxResolutionContext context)
    {
        _logger.LogInformation("Kullanıcı haritalandı: {Id} -> {FullName}", source.Id, destination.FullName);
    }
}

// Profil Kaydı:
CreateMap<UserSource, UserDest>()
    .BeforeMap((src, dest) => dest.LogInfo = "Eşleştirme Başladı") // Inline delege
    .AfterMap<AuditLogAction>(); // DI bağımlı MappingAction

7. Rekürsif Derinlik (MaxDepth) ve Döngüsel Referanslar (PreserveReferences)

İlişkisel veritabanı modellerinde (Entity Framework nesneleri vb.) veya graf yapılarında sonsuz döngüleri önlemek için kullanılır:

CreateMap<Category, CategoryDto>()
    .MaxDepth(3) // Maksimum 3 derinlikte iç içe haritalama yap
    .PreserveReferences(); // Aynı nesne referansını yakaladığında cache'ten dönerek sonsuz döngüyü engeller

8. Kalıtım ve Polimorfik Haritalama (Include / IncludeBase)

Türetilmiş (derived) sınıflar arasında polimorfik haritalamayı yönetmek için kullanılır:

CreateMap<Animal, AnimalDto>()
    .Include<Dog, DogDto>()
    .Include<Cat, CatDto>();

CreateMap<Dog, DogDto>()
    .IncludeBase<Animal, AnimalDto>(); // Base sınıftaki tüm eşleştirme kurallarını miras al

9. Derin Yol Eşleme (ForPath)

İç içe geçmiş hedef property hiyerarşisine derinlemesine atama yapmak için kullanılır. Hedef yoldaki ara nesneler null ise otomatik olarak yeni örnekleri (instantiation) oluşturulur.

CreateMap<OrderSource, OrderDest>()
    .ForPath(dest => dest.Shipping.Address.City, opt => opt.MapFrom(src => src.CityName));

10. Yapıcı Metot Eşleme (ForCtorParam) ve [VeloxConstructor]

Hedef tipte varsayılan parametresiz constructor yoksa veya constructor parametrelerini özel eşlemek istiyorsanız kullanılır:

CreateMap<UserSource, ImmutableUserDest>()
    .ForCtorParam("userName", opt => opt.MapFrom(src => src.LoginName));

Hedef tipte birden fazla yapıcı metot (constructor) varsa, VeloxMapper'ın hangisini kullanacağını açıkça belirtmek için [VeloxConstructor] attribute'unu kullanabilirsiniz:

public class ImmutableUserDest
{
    public string UserName { get; }
    public string Email { get; }

    // VeloxMapper bu constructor'ı kullanacaktır:
    [VeloxConstructor]
    public ImmutableUserDest(string userName, string email)
    {
        UserName = userName;
        Email = email;
    }

    public ImmutableUserDest(string userName)
    {
        UserName = userName;
        Email = "unknown@domain.com";
    }
}

11. Global Değer Dönüştürücüler (ValueTransformers)

Belirli bir veri tipindeki tüm özellik atamalarına global veya profil bazlı bir dönüştürme kuralı uygular:

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<UserSource, UserDest>();
    
    // Global olarak tüm string atamalarda Trim() işlemi yap ve null ise boş string'e çevir
    cfg.ValueTransformers.Add<string>(val => val?.Trim() ?? string.Empty);
});

⚙️ Global Konfigürasyon Ayarları

MapperConfiguration oluşturulurken kullanılan global yapılandırma seçenekleri:

using VeloxMapper.Abstractions;

var config = new MapperConfiguration(cfg =>
{
    // 1. Global Ignore: Belirtilen property adlarını tüm eşlemelerde yoksay
    cfg.AddGlobalIgnore("CreatedDate", "UpdatedDate", "Token");

    // 2. Prefix & Postfix Tanıma: Özellik isimlerindeki ön ek ve son ekleri kırparak eşleştir
    cfg.RecognizePrefixes("m_", "_", "Get");
    cfg.RecognizeDestinationPrefixes("m_"); // Sadece hedef property ön ekleri için
    cfg.RecognizePostfixes("Prop", "Value");

    // 3. Custom Naming Conventions (ICustomNamingConvention): PascalCase -> camelCase vb. dönüşümleri otomatik yap
    cfg.NamingConvention = new CamelCaseCustomNamingConvention();

    // 4. Diagnostics Sink (IVeloxDiagnosticsSink): Eşleşmeyen property veya mapping detaylarını log sisteminize yönlendirin
    cfg.DiagnosticsSink = new FileDiagnosticsSink();

    // 5. ForAllMaps: Kaydedilen tüm haritalama tanımlarına toplu kural/kancalar uygulayın
    cfg.ForAllMaps(reg =>
    {
        // Örnek: Tüm haritalara Before/After kancası veya ek kurallar eklenebilir
        reg.BeforeMapActions.Add(new Action<object, object>((src, dest) => {
            // Global BeforeMap mantığı
        }));
    });
});
Örnek ICustomNamingConvention Implementasyonu:
using VeloxMapper.Abstractions;

/// <summary>
/// PascalCase özellikleri camelCase hedeflerle eşleştirmek için kullanılan isimlendirme kuralı.
/// </summary>
public class CamelCaseCustomNamingConvention : ICustomNamingConvention
{
    public string Normalize(string propertyName)
    {
        if (string.IsNullOrEmpty(propertyName) || !char.IsUpper(propertyName[0]))
            return propertyName;

        return char.ToLower(propertyName[0]) + propertyName[1..];
    }
}
Örnek IVeloxDiagnosticsSink Implementasyonu:
using VeloxMapper.Abstractions;
using System.Diagnostics;

/// <summary>
/// Haritalama çalışma zamanı uyarılarını hata ayıklama penceresine basan sink.
/// </summary>
public class DebugDiagnosticsSink : IVeloxDiagnosticsSink
{
    public void Log(string message, string severity = "Information", string? sourceFile = null, int? lineNumber = null)
    {
        Debug.WriteLine($"[VeloxMapper - {severity}] {message} (File: {sourceFile ?? "N/A"}, Line: {lineNumber?.ToString() ?? "N/A"})");
    }
}

🚀 Çift Katmanlı (Layered) Çalışma Mantığı

VeloxMapper'ı benzersiz kılan, derleme zamanı ile çalışma zamanını birleştiren hibrit yapısıdır.

Layer 1: Source Generator (NativeAOT & Zero Allocation)

Eğer sınıfınızı [VeloxMap] niteliğiyle işaretlerseniz, Roslyn derleme zamanında (compile-time) doğrudan statik C# kodları üretir. Bu sayede hiçbir reflection ve çalışma zamanı yükü olmadan haritalama yapabilirsiniz.

Kritik Namespace Bilgisi: Source Generator tarafından üretilen tüm extension metotlar VeloxMapper.Generated isim uzayı (namespace) altında oluşturulur. Üretilen extension metotları (MapTo...) kullanabilmek için kodunuza mutlaka using VeloxMapper.Generated; satırını eklemelisiniz.

Kullanım Örneği:
using VeloxMapper.Attributes;

namespace MyProject.Models
{
    [VeloxMap(typeof(UserSource), typeof(UserDest))]
    public class UserSource
    {
        public string FirstName { get; set; } = string.Empty;
        public string LastName { get; set; } = string.Empty;
    }
}

Üretilen extension metodun kullanımı:

using MyProject.Models;
using MyProject.Dtos;
// Üretilen extension metotları kullanmak için bu namespace'i eklemelisiniz!
using VeloxMapper.Generated; 

public class UserService
{
    public UserDest ConvertUser(UserSource source)
    {
        // Reflection içermeyen, statik ve en hızlı şekilde haritalama gerçekleştirilir:
        return source.MapToMyProjectDtosUserDest(); 
    }
}

Layer 2: Runtime Expression Tree Engine

[VeloxMap] ile işaretlenmemiş sınıflar için dinamik plan çıkarılır. Expression Tree mimarisi kullanılarak bir kez strongly-typed delegate derlenir ve önbelleğe alınır. Sonraki haritalamalarda doğrudan bu compiled delege çağrıldığı için performans son derece yüksektir.


🔍 EF Core Projeksiyon Desteği (ProjectTo)

Veritabanından DTO çekerken performans kaybı yaşamamak için ProjectTo yeteneğini kullanabilirsiniz. VeloxMapper, Expression Tree planını doğrudan EF Core veritabanı sorgusuna (SQL SELECT ifadesine) dönüştürür.

using VeloxMapper.Extensions;

public List<UserDto> GetUserDtos(MyDbContext dbContext, IVeloxMapper mapper)
{
    return dbContext.Users
        .ProjectTo<UserDto>(mapper) // IQueryable üzerine yazar
        .ToList();                  // SQL SELECT Id, FullName... şeklinde veritabanında çalıştırılır
}

Güvenlik Sınırı: VeloxMapper, EF Core'un destekleyemediği ve veritabanında çalıştırılamayacak kullanıcı tanımlı metot çağrılarını projeksiyon planlarında reddeder ve erken hata (VeloxProjectionException) fırlatır.


📈 Gözlemlenebilirlik (Observability) & Snapshot Testleri

VeloxMapper, büyük ölçekli ve kurumsal projelerde haritalama şemalarındaki değişiklikleri CI/CD süreçlerinde izlemek için deterministik hash desteği sunar. Haritalama planları (MappingPlanDef) üzerinden SHA-256 hash'leri üreterek şema değişikliklerini test edebilirsiniz.

using VeloxMapper.Diagnostics;
using VeloxMapper.Configuration;

var plan = config.GetMappingPlan(typeof(UserSource), typeof(UserDest));

// Okunabilir metin veya JSON raporu üretin
string readablePlanText = MappingPlanReport.GenerateTextReport(plan);
string rawJsonPlan = MappingPlanReport.GenerateJsonReport(plan);

// Deterministik şema hash'ini alın (SHA-256)
string planHash = MappingPlanReport.GenerateHash(plan);

Snapshot Testi Yazma Örneği (xUnit)

Bu yöntemle, bir geliştirici kazara DTO property ismini değiştirdiğinde veya eşleştirmeyi bozduğunda CI pipeline'ınız hata vererek testi kıracaktır:

[Fact]
public void MappingPlans_ShouldMatch_ApprovedSnapshot()
{
    var config = new MapperConfiguration(cfg =>
    {
        cfg.AddProfile<UserMappingProfile>();
    });

    var plan = config.GetMappingPlan(typeof(UserSource), typeof(UserDest));
    string currentHash = MappingPlanReport.GenerateHash(plan);
    
    string expectedHash = "ff1f514ac56ca5be76cf0339013e2b49a7725f2696cf249b62bdc43f1b49b8e6"; // Önceden onaylanmış hash
    
    Assert.Equal(expectedHash, currentHash);
}

🛡️ Hata Tipleri (Exception Reference)

VeloxMapper'da oluşan tüm hatalar VeloxException tabanlıdır.

  • VeloxConfigurationException: Yapılandırma hatalarında fırlatılır (örn. startup doğrulaması AssertConfigurationIsValid başarısız olduğunda veya çakışan profiller tanımlandığında).
  • VeloxMappingException: Çalışma zamanında haritalama işlemi esnasında oluşabilecek olağan dışı tür uyuşmazlığı hatalarında fırlatılır.
  • VeloxProjectionException: ProjectTo içinde EF Core veya veritabanı tarafından desteklenmeyecek geçersiz bir expression tespit edildiğinde fırlatılır.
  • VeloxAmbiguousConstructorException: Hedef sınıfta birden fazla constructor bulunup hangisinin kullanılacağı belirsiz olduğunda fırlatılır (Çözüm için [VeloxConstructor] attribute'unu kullanın).

🤖 AI Agent Geçiş İstemi (One-Shot AI Migration Prompt)

Eğer projenizi Cursor, GitHub Copilot, Windsurf veya benzeri bir AI kod asistanı (Agent) kullanarak AutoMapper'dan VeloxMapper'a geçirmek istiyorsanız, aşağıdaki prompt'u kopyalayıp asistanınıza doğrudan verebilirsiniz. Bu prompt, yapay zekanın geçişi tek seferde ve hatasız yapmasını sağlayacaktır:

Aşağıdaki kuralları ve eşleşmeleri uygulayarak bu projeyi AutoMapper'dan tamamen temizleyip VeloxMapper kütüphanesine geçir:

1. Bağımlılık Güncellemeleri:
   - Projedeki tüm "AutoMapper" ve "AutoMapper.Extensions.Microsoft.DependencyInjection" NuGet paket referanslarını kaldır.
   - Yerine "VeloxMapper" NuGet paketini ekle.

2. İsim Uzayları ve Sınıf Dönüşümleri:
   - "using AutoMapper;" satırlarını "using VeloxMapper;" veya "using VeloxMapper.Configuration;" olarak değiştir.
   - "Profile" sınıfından türeyen sınıfları "VeloxProfile" sınıfından türet.

3. Haritalama (Mapping) API Eşleştirmeleri:
   - "CreateMap<TSource, TDest>()" API'leri aynı kalacak.
   - ".ForMember(dest => dest.X, opt => opt.MapFrom(src => ...))" ifadelerini birebir koru.
   - ".ForMember(dest => dest.X, opt => opt.MapFrom<TResolver>())" ifadelerini "opt.MapFrom<TResolver>()" olarak güncelle. TResolver sınıfının "IVeloxValueResolver<TSource, TDestination, TMember>" implemente etmesini sağla.
   - ".ForMember(dest => dest.X, opt => opt.MapFrom<TResolver, TSourceMember>(src => src.Member))" ifadelerini "opt.MapFrom<TResolver, TSourceMember>(src => src.Member)" olarak koru. TResolver sınıfının "IVeloxMemberValueResolver<TSource, TDestination, TSourceMember, TMember>" implemente etmesini sağla.
   - ".ForMember(dest => dest.X, opt => opt.ConvertUsing<TConverter, TSourceMember>(src => src.Member))" ifadelerini "opt.ConvertUsing<TConverter, TSourceMember>(src => src.Member)" olarak koru. TConverter sınıfının "IVeloxValueConverter<TSourceMember, TMember>" implemente etmesini sağla.
   - "CreateMap<TSource, TDest>().ConvertUsing(new MyTypeConverter())" ifadelerini koru. Converter'ın "IVeloxTypeConverter<TSource, TDest>" implemente etmesini sağla.
   - ".ForMember(dest => dest.X, opt => opt.Ignore())" ifadelerini birebir koru.
   - ".ForMember(dest => dest.X, opt => opt.Condition((src, dest, val) => ...))" ifadelerini koru.
   - ".ForMember(dest => dest.X, opt => opt.PreCondition(src => ...))" ifadelerini koru.
   - ".ForMember(dest => dest.X, opt => opt.NullSubstitute(value))" ifadelerini koru.
   - ".ReverseMap()", ".ConstructUsing(src => ...)", ".MaxDepth(depth)", ".PreserveReferences()" ve ".ForPath(...)" ifadelerini birebir koru.
   - ".Include<TDerivedSource, TDerivedDestination>()" ve ".IncludeBase<TBaseSource, TBaseDestination>()" ifadelerini koru.
   - ".ForAllMembers(opt => opt.Ignore())" ve ".ForAllMembers(opt => opt.Condition((src, dest, val) => ...))" ifadelerini koru.

4. Servis ve Sorgu Projeksiyonları:
   - Sınıflardaki "IMapper" bağımlılıklarını ve enjeksiyonlarını "IVeloxMapper" olarak değiştir.
   - EF Core sorgularındaki "ProjectTo<TDest>(mapper)" veya "mapper.ProjectTo<TDest>(queryable)" kullanımlarını "queryable.ProjectTo<TDest>(mapper)" extension metodu şeklinde düzelt ("using VeloxMapper.Extensions;" eklemeyi unutma).

5. Yaşam Döngüsü Kancaları (BeforeMap/AfterMap):
   - ".BeforeMap((src, dest) => ...)" ve ".AfterMap((src, dest) => ...)" delegelerini koru.
   - Sınıf tabanlı ".BeforeMap<TAction>()" ve ".AfterMap<TAction>()" çağrılarını koru (TAction'ların IVeloxMappingAction<TSource, TDest> implemente etmesini sağla).

6. Startup ve Dependency Injection Kayıtları:
   - "services.AddAutoMapper(...)" satırlarını bul ve şu şekilde AddVeloxMapper ile değiştir:
     services.AddVeloxMapper(cfg => 
     {
         cfg.AddProfilesFromAssembly(typeof(BelirliBirProfil).Assembly);
         // Gerekirse global kuralları ekle:
         // cfg.AddGlobalIgnore("CreatedDate");
         // cfg.RecognizePrefixes("m_");
         // cfg.AllowNullCollections = true;
         // cfg.NamingConvention = new MyNamingConvention();
     });
   - Eğer DI kullanılmayan bağımsız bir Mapper kurulumu varsa, "new MapperConfiguration(...)" sonrasında mutlaka "config.AssertConfigurationIsValid();" çağrısını ekle.

7. Fail-Fast Uyumluluk Kuralı (Kritik):
   - VeloxMapper katı bir doğrulama (fail-fast) mimarisine sahiptir. Eşleştirilen kaynak ve hedef tipler arasında birebir isim eşleşmesi (case-insensitive, prefix/postfix veya convention'lar hariç) olmayan veya açık kuralla belirtilmeyen tüm hedef özellikleri startup doğrulaması sırasında hata fırlatır.
   - Bu nedenle geçiş yaparken, eğer hedef tipte olup kaynak tipte karşılığı olmayan özellikler varsa, bunları açıkça ".ForMember(dest => dest.Ozellik, opt => opt.Ignore())" olarak konfigüre et.

Tüm dosyaları tarayarak bu geçişi tek seferde tamamla. Kodun derlenebilir ve hatasız olduğundan emin ol.

📄 Lisans

Bu proje MIT Lisansı ile lisanslanmıştır. Kurumsal ve bireysel projelerinizde ücretsiz olarak güvenle kullanabilirsiniz.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.1.1 110 5/22/2026
4.1.0 112 5/22/2026
4.0.3 116 5/22/2026
4.0.2 98 5/22/2026
4.0.1 97 5/21/2026
4.0.0 104 5/21/2026
3.1.0 116 4/8/2026