C# 3.0 ile beraber gelen partial class yapısını artık ister istemez bir
çoğumuz kullanıyoruz. Visual Studio Designer'ları aracılığı ile
oluşturulan sınıflar genellikle partial class olarak oluşturulur.
Partial class ların ne olduğunu kısaca hatırlamak gerekirse; fiziksel
olarak yada aynı fiziksel dosyada (amacına göre ayrı iki .cs dosyasında
olması makbul ve mantıklıdır) tanımlanan class tanımlarının tek bir
class olarak çalışması ve derlenmesidir. Yani aslında bir sınıfın
methodların farklı .cs dosyalarında tanımalayabilmeyi sağlar.
Kısaca
ApprovalDocument.cs içinde aşağıdaki property ve methodların olduğunu varsayalım.
public partial class ApprovalDocument
{
public string DocumentName { get; set; }
public bool Delete()
{
//delete işleri...
return true;
}
public bool Save()
{
//persistency için gerekli işler buraya...
return true;
}
}
ApprovalDocument.2.cs gibi bir yeni dosya oluşturup içine aşağıdaki kod bloğunu ekleyelim.
public partial class ApprovalDocument
{
public bool GetBackDeletedApproval()
{
//silinen bir onay dokümanını geri almak için gerekli kodlar....
return true;
}
}
ApprovalDocument sınıfı tek bir sınıftır ancak iki farklı dosyada yer almaktadır. Aşağıdaki gibi kullanılabilir.
ApprovalDocument aDoc = new ApprovalDocument();
aDoc.DocumentName = "Test";
aDoc.Delete();
aDoc.GetBackDeletedApproval(); //2.dosyada yazdığımız method
Partial Methods
Partial sınıfları hatırladıktan sonra karşılaşılan bir zorluktan ve bunun çözümünden, yani partial methods lardan bahsedelim.
Yukarıkdaki örnekte olduğu gibi partial class lar genellikle kullanıcı
tarafından oluşturulmazlar aslında, en çok kullanımının görüldüğü yer
Visual Studio Designerları, code generator araçları (CodeSmith,
NVelocity gibi.) ya da başka bir araç tarafından otomatik oluşturulan
sınıflara ekleme yapmak için kullanılır.
Örneğin Visual Studio Designer'ları otomatik oluşturdukları sınıfı partial yaparlar ve kullanıcı için
otomatikolusansinifadi.user.cs gibi
(zorunlu değil ama kabul görmüş bir isimlendirme) dosya oluşturup
içerisine aynı namespace altında ve aynı isme sahip bir partial class
eklenerek otomatik oluşturulan sınıfa eklemeler yapılabilir. İş
hayatımda kendi hazırladığımız kod üreten Visual Studio Designerları
yazmamız gerekti ve otomatik oluşturulan bir dosyanın yanına .user.cs
eki ile biten bir dosya daha oluşturtuyoruz. user.cs dosyası zaten ilk
kayıtta oluşturulduysa ikinci defa üzerine yazmıyoruz. Visual Studio
ile builtin gelen designerlarda aynı şekilde çalışmaktadır ve her zaman
otomatik oluşturulan kodun yer aldığı dosyanın en üstünde bu dosya
autogenerated'dır içeriğini değiştirmeyiniz şeklinde uyarmaktadır. Zira
tekrar designer kayıt yaptığında bildiği kodu oluşturmaktadır. Biz ise
otomatik oluşturulan kod dışında user.cs gibi dosyalara kodumuzu
yazarak otomatik oluşturulan partial class'a eklentimizi yaparız.
Burada şöyle bir senarya oluşturulım ve sorunu tanımlayalım.
Aşağıdaki ApprovalDocument.cs nin bir şekilde otomatik oluşturulduğunu düşünelim.
public partial class ApprovalDocument
{
public string DocumentName { get; set; }
public bool Delete()
{
//delete işleri...
return true;
}
public bool Save()
{
//persistency için gerekli işler buraya...
return true;
}
}
Bu partial sınıfa bir ekleme yapmak için ApprovalDocument.user.cs
oluşturalım. Ancak istenen şey otomatik oluşturulan Save methodu
çalışmadan önce bazı custom validation işlerimini yapması ve ona göre
işine devam etmesi olsun. Bu durumda CustomValidation methodu user.cs
dosyası içerisine yazılmalıdır. Ancak Save işleminden hemen önce
otomatik çalışması nasıl sağlanacak? Otomatik oluşan kodumuzu aşağıdaki
oluşturulacak şekle getirelim;
public partial class ApprovalDocument
{
public string DocumentName { get; set; }
private bool _isValid = false;
partial void CustomValidation();
public bool Delete()
{
//delete işleri...
return true;
}
public bool Save()
{
CustomValidation();
if (_isValid)
{
//persistency için gerekli işler buraya...
}
return true;
}
}
Yukarıdaki otomatik oluşturulan kodda yapmamız gereken değişiklikleri kalın olarak belirttim.
partial void CustomValidation(); olarak tanımlanan satır ile bir method
tanımlanıyor ancak implementasyonu yok, partial method olarak
tanımlanması sayesinde otomatik oluşturulan kod içinde Save method
içerisinde CustomValidation metodu çağrılır. Ve biz CustomValidation
partial methodunu partial class oluşturarak eklemezisek bu method
çağrısı hiç bir şey yapmayacak ve hata da vermeyecektir. _isValid
değeri her zaman false kalacaktır.
ApprovalDocument.user.cs içerisini aşağıdaki gibi düzenlemeyelim.
public partial class ApprovalDocument
{
public bool GetBackDeletedApproval()
{
//silinen bir onay dokümanını geri almak için gerekli kodlar....
return true;
}
partial void CustomValidation()
{
this._isValid = true;
}
}
Bu şekilde otomatik oluşturulan kodun akışı içerisine kendi kodumuzu
dahil etmiş oluyoruz. Sadece method ekleyerek bunu yapamayız ancak
otomatik oluşturulan kodunuz size bu olanağı sunuyor ise akışın
içerisine dahil olabilirsiniz.
Partial methodlar yokken bunu nasıl yapabilirdik? Event'ler ile bu
yapılabilirdi ancak bu şekilde daha şık ve doğru bir yapı olduğunu
düşünüyorum.
Partial methodlar ile kendi yazdığınız kodlar dışında nerede
karşılaşabilir ve kullanabilirsiniz? Örneğin LINQ to SQL Designer'ı
ürettiği kodda partial methodlar tanımlamaktadır ve bunların
implementasyonunu ekleyerek custom validation gibi işlemler
yapabilirsiniz. LINQ to SQL Designer'ının partial method örneği için
tıklayınız.