Skip to content

Entity Framework - Value Objects

Giriş

Entity Framework'te Value Objects (Değer Nesneleri), kimlikleri olmayan ve değişmez (immutable) olan nesnelerdir. Mid-level geliştiriciler için bu kavramın anlaşılması ve etkin kullanımı önemlidir.

Value Objects'ın Önemi

  1. Domain Model
  2. Zengin domain model
  3. Daha iyi encapsulation
  4. Daha iyi validasyon
  5. Daha iyi business logic

  6. Veri Bütünlüğü

  7. Immutability
  8. Validation
  9. Consistency
  10. Integrity

  11. Bakım

  12. Daha az kod tekrarı
  13. Daha kolay test edilebilirlik
  14. Daha iyi okunabilirlik
  15. Daha kolay bakım

Value Objects Özellikleri

  1. Temel Value Object

    public class Address : ValueObject
    {
        public string Street { get; }
        public string City { get; }
        public string State { get; }
        public string ZipCode { get; }
    
        public Address(string street, string city, string state, string zipCode)
        {
            Street = street;
            City = city;
            State = state;
            ZipCode = zipCode;
        }
    
        protected override IEnumerable<object> GetEqualityComponents()
        {
            yield return Street;
            yield return City;
            yield return State;
            yield return ZipCode;
        }
    }
    

  2. Money Value Object

    public class Money : ValueObject
    {
        public decimal Amount { get; }
        public string Currency { get; }
    
        public Money(decimal amount, string currency)
        {
            if (amount < 0)
                throw new ArgumentException("Amount cannot be negative");
    
            if (string.IsNullOrEmpty(currency))
                throw new ArgumentException("Currency cannot be empty");
    
            Amount = amount;
            Currency = currency;
        }
    
        public Money Add(Money other)
        {
            if (Currency != other.Currency)
                throw new InvalidOperationException("Cannot add money with different currencies");
    
            return new Money(Amount + other.Amount, Currency);
        }
    
        protected override IEnumerable<object> GetEqualityComponents()
        {
            yield return Amount;
            yield return Currency;
        }
    }
    

  3. Complex Value Object

    public class FullName : ValueObject
    {
        public string FirstName { get; }
        public string LastName { get; }
    
        public FullName(string firstName, string lastName)
        {
            if (string.IsNullOrEmpty(firstName))
                throw new ArgumentException("First name cannot be empty");
    
            if (string.IsNullOrEmpty(lastName))
                throw new ArgumentException("Last name cannot be empty");
    
            FirstName = firstName;
            LastName = lastName;
        }
    
        public string GetFullName() => $"{FirstName} {LastName}";
    
        protected override IEnumerable<object> GetEqualityComponents()
        {
            yield return FirstName;
            yield return LastName;
        }
    }
    

Value Objects Kullanımı

  1. Entity İçinde Kullanım

    public class Customer : Entity
    {
        public FullName Name { get; private set; }
        public Address Address { get; private set; }
        public Money Balance { get; private set; }
    
        public Customer(FullName name, Address address, Money balance)
        {
            Name = name;
            Address = address;
            Balance = balance;
        }
    
        public void UpdateAddress(Address newAddress)
        {
            Address = newAddress;
        }
    
        public void AddMoney(Money amount)
        {
            Balance = Balance.Add(amount);
        }
    }
    

  2. DbContext Konfigürasyonu

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>(entity =>
        {
            entity.OwnsOne(c => c.Name, name =>
            {
                name.Property(n => n.FirstName).HasColumnName("FirstName");
                name.Property(n => n.LastName).HasColumnName("LastName");
            });
    
            entity.OwnsOne(c => c.Address, address =>
            {
                address.Property(a => a.Street).HasColumnName("Street");
                address.Property(a => a.City).HasColumnName("City");
                address.Property(a => a.State).HasColumnName("State");
                address.Property(a => a.ZipCode).HasColumnName("ZipCode");
            });
    
            entity.OwnsOne(c => c.Balance, money =>
            {
                money.Property(m => m.Amount).HasColumnName("BalanceAmount");
                money.Property(m => m.Currency).HasColumnName("BalanceCurrency");
            });
        });
    }
    

  3. Value Object Dönüşümleri

    // Value Object to String
    public static class AddressExtensions
    {
        public static string ToString(this Address address)
        {
            return $"{address.Street}, {address.City}, {address.State} {address.ZipCode}";
        }
    }
    
    // String to Value Object
    public static class AddressParser
    {
        public static Address Parse(string addressString)
        {
            var parts = addressString.Split(',');
            if (parts.Length != 3)
                throw new ArgumentException("Invalid address format");
    
            var cityStateZip = parts[2].Trim().Split(' ');
            if (cityStateZip.Length != 3)
                throw new ArgumentException("Invalid address format");
    
            return new Address(
                parts[0].Trim(),
                parts[1].Trim(),
                cityStateZip[0],
                cityStateZip[2]);
        }
    }
    

Best Practices

  1. Value Object Tasarımı
  2. Immutability
  3. Validation
  4. Equality
  5. Business logic

  6. Güvenlik

  7. Input validation
  8. Data integrity
  9. Access control
  10. Audit logging

  11. Performans

  12. Memory usage
  13. Equality comparison
  14. Serialization
  15. Caching

  16. Bakım

  17. Code organization
  18. Documentation
  19. Testing
  20. Versioning

Mülakat Soruları

Temel Sorular

  1. Entity Framework'te Value Object nedir?
  2. Cevap: Value Object, kimliği olmayan ve değişmez (immutable) olan bir nesnedir.

  3. Entity Framework'te Value Object ve Entity arasındaki fark nedir?

  4. Cevap: Entity'lerin kimlikleri vardır ve değişebilir, Value Object'lerin kimlikleri yoktur ve değişmezdir.

  5. Entity Framework'te Value Object nasıl konfigüre edilir?

  6. Cevap: DbContext.OnModelCreating metodunda OwnsOne metodu kullanılarak konfigüre edilir.

  7. Entity Framework'te Value Object ne zaman kullanılır?

  8. Cevap: Değerlerin bir bütün olarak ele alınması gerektiğinde ve değişmezlik gerektiğinde kullanılır.

  9. Entity Framework'te Value Object performansı nasıl etkiler?

  10. Cevap: Memory kullanımını artırabilir ancak domain modeli zenginleştirir ve kod kalitesini artırır.

Teknik Sorular

  1. Temel Value Object nasıl oluşturulur?
  2. Cevap:

    public class Address : ValueObject
    {
        public string Street { get; }
        public string City { get; }
        public string State { get; }
        public string ZipCode { get; }
    
        public Address(string street, string city, string state, string zipCode)
        {
            Street = street;
            City = city;
            State = state;
            ZipCode = zipCode;
        }
    
        protected override IEnumerable<object> GetEqualityComponents()
        {
            yield return Street;
            yield return City;
            yield return State;
            yield return ZipCode;
        }
    }
    

  3. Money Value Object nasıl oluşturulur?

  4. Cevap:

    public class Money : ValueObject
    {
        public decimal Amount { get; }
        public string Currency { get; }
    
        public Money(decimal amount, string currency)
        {
            if (amount < 0)
                throw new ArgumentException("Amount cannot be negative");
    
            if (string.IsNullOrEmpty(currency))
                throw new ArgumentException("Currency cannot be empty");
    
            Amount = amount;
            Currency = currency;
        }
    
        public Money Add(Money other)
        {
            if (Currency != other.Currency)
                throw new InvalidOperationException("Cannot add money with different currencies");
    
            return new Money(Amount + other.Amount, Currency);
        }
    
        protected override IEnumerable<object> GetEqualityComponents()
        {
            yield return Amount;
            yield return Currency;
        }
    }
    

  5. Value Object DbContext'te nasıl konfigüre edilir?

  6. Cevap:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>(entity =>
        {
            entity.OwnsOne(c => c.Address, address =>
            {
                address.Property(a => a.Street).HasColumnName("Street");
                address.Property(a => a.City).HasColumnName("City");
                address.Property(a => a.State).HasColumnName("State");
                address.Property(a => a.ZipCode).HasColumnName("ZipCode");
            });
        });
    }
    

  7. Value Object equality nasıl sağlanır?

  8. Cevap:

    protected override IEnumerable<object> GetEqualityComponents()
    {
        yield return Street;
        yield return City;
        yield return State;
        yield return ZipCode;
    }
    

  9. Value Object validation nasıl yapılır?

  10. Cevap:
    public Address(string street, string city, string state, string zipCode)
    {
        if (string.IsNullOrEmpty(street))
            throw new ArgumentException("Street cannot be empty");
    
        if (string.IsNullOrEmpty(city))
            throw new ArgumentException("City cannot be empty");
    
        if (string.IsNullOrEmpty(state))
            throw new ArgumentException("State cannot be empty");
    
        if (string.IsNullOrEmpty(zipCode))
            throw new ArgumentException("ZipCode cannot be empty");
    
        Street = street;
        City = city;
        State = state;
        ZipCode = zipCode;
    }
    

İleri Seviye Sorular

  1. Entity Framework'te Value Object performansı nasıl optimize edilir?
  2. Cevap:

    • Memory kullanımı optimizasyonu
    • Equality comparison optimizasyonu
    • Serialization optimizasyonu
    • Caching stratejileri
    • Lazy loading
  3. Entity Framework'te distributed sistemlerde Value Object nasıl yönetilir?

  4. Cevap:

    • Serialization
    • Versioning
    • Migration
    • Consistency
    • Conflict resolution
  5. Entity Framework'te high concurrency senaryolarında Value Object nasıl yönetilir?

  6. Cevap:

    • Immutability
    • Thread safety
    • Atomic operations
    • Versioning
    • Conflict resolution
  7. Entity Framework'te Value Object monitoring ve profiling nasıl yapılır?

  8. Cevap:

    • Memory profiling
    • Performance metrics
    • Resource monitoring
    • Profiling tools
    • Health checks
  9. Entity Framework'te custom Value Object stratejileri nasıl geliştirilir?

  10. Cevap:
    • Custom equality
    • Custom validation
    • Custom serialization
    • Custom conversion
    • Custom optimization