TemporaryPropertiesExtensions, mevcut sınıflarınızı hiç değiştirmeden herhangi bir reference type nesneye çalışma zamanında anahtar–değer verisi ekleyip yönetmenizi sağlayan, ConditionalWeakTable tabanlı, thread‑safe ve GC dostu bir extension kütüphanesidir.
Sadece işlem süresince ihtiyaç duyduğunuz bir alanı domain modeline eklemek, o modeli kalıcı olarak kirletir — üstelik database'e, serialization'a ve iş kurallarına hiç ait olmadan.
Domain modelinin bir parçası değil — sadece o anki işlem için var.
Database'e ait değil — bir ORM kolonuna dönüşmemeli.
Serialization'da görünmemeli — API contract'ını kirletmemeli.
Sadece mevcut işlem süresince gerekli — kalıcı bir state değil.
Belki üçüncü parti bir sınıf — kaynak koduna erişiminiz bile yok.
Aşağıdaki nesne üzerinde deneyin: Name alanına geçici bir değer ekleyin, GetWithTemporary'nin sonucunun nasıl değiştiğini — gerçek property'nin ise hiç dokunulmadığını — görün.
Gerçek nesne değişmez; temporary store nesnenin yaşam döngüsüne ConditionalWeakTable ile bağlanır, üzerine hiçbir fiziksel property eklenmez.
Henüz temporary değer eklenmedi — GetWithTemporary, gerçek property'yi (compiled getter cache üzerinden) okuyor.
Nesneye fiziksel property eklemeden geçici değer saklar.
x => x.Property şeklinde strongly-typed, IntelliSense destekli kullanım.
Property/field adına string ile, dinamik senaryolar için erişim.
Reflection maliyetini tekrar tekrar ödememek için getter'lar compile edilip cache'lenir.
Getter cache'i ConditionalWeakTable<Type,...> ile Type yaşam döngüsüne bağlanır.
Temporary store, nesneyi güçlü referansla tutmaz — GC'nin işini engellemez.
Store ve getter cache için ConcurrentDictionary kullanılır.
String dönüşümlerinde allocation azaltmak için ReadOnlySpan<char> kullanılır.
Numeric/date parsing önce Invariant, sonra Current Culture ile denenir.
IConvertible üzerinden farklı primitive tipler arasında otomatik dönüşüm.
String değerlerden case-insensitive enum dönüşümü.
Public ve non-public instance property/field erişimi desteklenir.
Kütüphane, temporary değerleri ve compiled getter'ları birbirinden tamamen ayrı iki ConditionalWeakTable yapısında tutar — biri nesne, diğeri Type yaşam döngüsüne bağlıdır.
Strongly-typed Expression API veya dinamik Name-Based API — ikisi de aynı temporary storage üzerinde çalışır, birbirinin yerine kullanılabilir.
Domain modelinin parçası olmayan, ama işlem sırasında ihtiyaç duyulan her runtime bilgisi için uygundur.
Bir API'den gelen DTO'ya, yalnızca response processing sırasında kullanılacak metadata eklenir — DTO'nun kendisine property eklemeye gerek kalmaz.
response.AddTemporaryByName("ProcessedAt", DateTime.UtcNow);
Bir nesne başka bir modele eşlenirken, işlemin durumunu geçici olarak nesnenin üzerinde taşıyabilirsiniz.
entity.AddTemporaryByName("MappingStatus", "Completed");
Database modelinin parçası olmayan; ValidationResult, ProcessingState, RuntimeScore gibi geçici bilgiler entity üzerinde tutulabilir.
entity.AddTemporaryByName("ValidationResult", result);
Bir nesnenin pipeline'ın hangi aşamasından geçtiği, aşamalar arasında nesne üzerinde geçici olarak saklanabilir.
item.AddTemporaryByName("ProcessingStage", "Validation");
Framework veya utility geliştirirken, kullanıcının sınıflarına dokunmadan Source, Validation, Cache State gibi metadata taşınabilir.
obj.AddTemporaryByName("Source", "ExternalSync");
Kaynak koduna müdahale edemediğiniz, başka bir kütüphaneden gelen sınıflar üzerinde bile runtime state taşıyabilirsiniz.
thirdPartyObject.AddTemporaryByName("RuntimeState", "Processed");
| Yaklaşım | Model Değişir mi? | GC Dostu | Thread-Safe | Dynamic | Getter Cache |
|---|---|---|---|---|---|
| Property eklemek | Evet | ✓ | Modele bağlı | ✗ | ✗ |
| Wrapper / Decorator | Hayır | ✓ | Modele bağlı | Kısmen | ✗ |
| Global Dictionary | Hayır | ⚠ | ⚠ | ✓ | ✗ |
| Her çağrıda Reflection | Hayır | ✓ | ✓ | ✓ | ✗ |
| ConditionalWeakTable + Reflection | Hayır | ✓ | ✓ | ✓ | Kısmen |
| TemporaryPropertiesExtensions | Hayır | ✓ | ✓ | ✓ | ✓ |
AddTemporaryExpression ile temporary değer eklerGetWithTemporaryExpression ile temporary/gerçek değeri getirirRemoveTemporaryExpression ile temporary değeri silerAddTemporaryByNameİsimle temporary değer eklerGetWithTemporaryByNameİsimle temporary/gerçek değeri getirirRemoveTemporaryByNameİsimle temporary değeri silerGetTemporaryPropertiesTemporary dictionary'yi getirirClearTemporaryNesnenin tüm temporary değerlerini temizlerClearGetterCacheFor(instance)Nesnenin Type'ına ait getter cache'ini temizlerClearGetterCacheFor<T>()Generic Type getter cache'ini temizlerClearGetterCacheFor<T,TProp>()Belirli member getter cache'ini temizlerKütüphane şu an tek bir kaynak dosya (TemporaryPropertiesExtensions.cs) olarak dağıtılıyor; harici hiçbir framework gerektirmez, temel .NET API'leri üzerine kuruludur.
TemporaryPropertiesExtensions, gerçek nesne modelinizi hiç değiştirmeden, nesnenin yaşam döngüsü boyunca ihtiyaç duyulan geçici bilgileri yönetmeniz için tasarlandı.
GitHub'da İncele →"Modelin parçası olmayan bilgiyi modele eklemek zorunda değilsin."