9 Temmuz 2013 Salı
Unit Of Work
Repository Pattern'deki transactional sorunları ortadan kaldırmak istiyorsan ve aynı business classının içerisinde kullanman gereken bir sürü repository nesnen var bunları tek bir birim altından yürütmek istiyorsan o zaman doğru adrese geldin . ( Bu arada unit of work illa repository ile kullanılacak diye bir kural yok birbirinden bağımsız da kullanılabilir ama ikisi bir olunca Zeki - Metin misali birbirlerini tamamlıyorlar adeta:) )
Örnekte Repository Pattern ile Unit Of Work patterni birlikte kullanacağım . Banka projesi üzerinde çalışıyoruz Müsteri ve Sube nesnelerimin olması yeterli.
public class Musteri
{
public int Id { get; set; }
public string Ad { get; set; }
public string Soyad { get; set; }
public decimal HesabındakiPara { get; set; }
}
public class Sube
{
public int Id { get; set; }
public decimal KasadakiPara { get; set; }
}
Repository classlarımın kullanacağı methodları imzalayalım;
public interface IMusteriRepository
{
void ParaEkle();
void ParaEksilt();
}
public interface ISubeRepository
{
void ParaAl();
void ParaGonder();
}
Repository classlarım;
public class SubeRepository : ISubeRepository
{
public void ParaAl(Sube sube, decimal miktar)
{
sube.KasadakiPara += miktar;
}
public void ParaGonder(Sube sube, decimal miktar)
{
sube.KasadakiPara -= miktar;
}
}
public class MusteriRepository:IMusteriRepository
{
public void ParaEkle(Musteri musteri, decimal miktar)
{
musteri.HesabındakiPara += miktar;
}
public void ParaEksilt(Musteri musteri, decimal miktar)
{
musteri.HesabındakiPara -= miktar;
}
}
Buraya kadar olan kısımda anlamadığınız birşey varsa repository pattern makalesine bir göz atmanızı rica ediyorum. Şimdi geldik dananın kuyruğunun koptuğu noktaya. UnitOfWork classımızı tanımlayayım;
public class UnitOfWork
{
private DatabaseContext _dbcontext = new DatabaseContext();
public MusteriRepository Musteriler { get; set; }
public SubeRepository SubeRepository { get; set; }
public void Save()
{
_dbcontext.SaveChanges();
}
}
Şimdi UnitOfWork classımızın işlevlerine bakalım ilk olarak repositoryleri property olarak tanımladık böylece veritabanı ile yapacağımız işlemleri tek bir nesnede topladık , ikinci olarak göze çarpan ayrıntı ise savechanges() metodunu yani modeldeki değişikliği git veritabanına kaydet diyen metod , save() metodu içine aldık bunu yapmamızdaki sebep transaction sağlıklı işlemesini sağlamak , küçük bir örnekle hemen anlatayım.
var unitOfWork = var UnitOfWork();
var musteri1 = var Musteri() {Ad = "Ali", HesabındakiPara=49};
var musteri2 = var Musteri() {Ad = "Veli", HesabındakiPara = 50};
unitOfWork.Musteriler.ParaEksilt(musteri1, 10);
unitOfWork.Musteriler.ParaEkle(musteri2, 10);
unitOfWork.Save();
Yukarıdaki kod anlaşıldığı gibi aliden 10 para alıp, Veliye 10 para veriyor. Şimdi biz savechanges() metodumuzu repository classlarımızda kullansaydık yaptığımız her değişiklik veritabanına yansırdı mesela alinin parasını azalttığımız anda server'ımıza enerji kaynağı veren trafo üzerine meteor düşerse ve ya elektrik kesilip jeneratör'ün de mazotu biterse naparız (tamam biraz uç nokta oldu ama şu an aklıma başka felaket senaryosu gelmedi :)) Veli'ye de ekleyemeyeceğiz. Ee para nerde (araba nerde :)) uçtu. İşte unit of Work kullanarak repository'nin eksik kalan kısmını, kanayan yarasını yani transaction sorununu ortadan kaldırıyoruz ,Ali'den para eksilmesi ile Veli'ye para eklenmesini aynı anda veritabanına kaydolmasını sağlıyoruz.
Benden bu kadar hadi selametle :)
Kaydol:
Kayıt Yorumları (Atom)
:) Harika, Veli artık mutlu...
YanıtlaSilTeşekkürler :)
YanıtlaSilÇok teşekkürler.
YanıtlaSilGüzel bir makale olmuş teşekkürler. Repository kullanımını biliyor ancak UnitOfWork bilmiyorum, sayenizde öğrendim.
YanıtlaSilÇok sade anlaşılır olmuş,teşekürler...
YanıtlaSilGerçenten sade ve nokta atışı anlatım olmuş, Teşekkürler.
YanıtlaSil