Lazy Loading için Repository Örneği

Merhabalar herkese. Kısa bir aradan sonra tekrar buradayım. Asp.Net projelerinde Lazy Loading kullanımının sakıncalı bir durum olduğundan bir yazımda söz etmiştim. Lazy Loading kullanmadan web sayfalarımızın hızını ciddi oranda arttırabiliriz. Peki gelelim katmanlı mimari yapısına… Hemen hemen herkes Asp.net projelerinde repository pattern’i kullanır. Generic metotlar sayesinde işlemlerimizi kolay bir şekilde gerçekleştirebiliriz. Lazy Loading içinde uygun metotlar yazabiliriz. Linq extension metotlarından Include metodu tamda bizim ihtiyacımızı görüyor. Şimdi gelelim basit ama kullanışlı bir repository pattern örneğini inceleyelim. Tabi tüm bu mekanizma için katmanlı mimari kullanımı çok önemli.

Öncelikle katmanlarımızı oluşturalım. Katmanlarımız ufak bir proje için şu şekilde olmalıdır. Örneğin projemizin ismi SeizeTheDay olsun.

  • SeizeTheDay.Business
  • SeizeTheDay.Common
  • SeizeTheDay.DataAccess
  • SeizeTheDay.Entities
  • SeizeTheDay.WebUI

Takdir edersiniz ki veri tabanından gelen entity sınıflarımız .Entities adlı katmanımızda yer almaktadır. Repository Pattern’in bulunduğu katman ise DataAccess olacaktır. Şimdi adımlarımıza başlayalım.

1.Adım Klasörleri Oluşturmak

Bahsettiğim gibi repository pattern .DataAccess katmanımızda yer alacak. Ben bu yapıyı SeizeTheDay adlı projemde kullandım. Fakat veri tabanı olarak MySQL kullanmıştım. EntityFramework ile hemen hemen aynı yapı zaten.

DataAccess katmanımız için klasörleme şu şekildedir. Bahsettiğim gibi bu projede MySQL kullandığımdan dolayı MySQL adlı bir klasör oluşturma gereksinimi duydum. Siz Mssql kullanıyorsanız Interface ve classlarınızı EntityFramework adlı klasörde barındırmalısınız.

Örneğin Abstract adlı klasörün içi şu şekildedir. Abstract adlı klasörümüzün içinde aslında bir nevi soyut adını verdiğimiz interface sınıflarımız yer alacaktır. Bu sınıfların içerilerinde imza adını verdiğimiz metotlar yer alacaktır. Dikkat edilmesi gereken husus şudur, veri tabanında ki her bir entity’e yani tabloya denk gelecek bu interfacelerimizi oluşturmamızdır. Bu interface’lerin içinde birde IEntityRepository adını verdiğimiz bizim için önemli bir sınıfımız bulunmakta. Repository’e ait tüm imzalarımız burada bulunmakta. İşte Lazy Loading içinde birbirinden önemli imzalarımızı burada barındırıp gerekli Conrete sınıfından bu interface’i implement edeceğiz. Şimdi gelelim IEntityRepository adlı interface’imizi incelemeye.

2.Adım Interface’leri Oluşturmak

IEntityRepository interface’imiz şu şekildedir.

Burada dikkat edilmesi gereken husus EntityObject adlı nesnenin MySQL için kullanılması. Neden bunu kullanmam gerektiğine dair bilgi vermem gerekirse, MySQL’i projede kullanabilmek için Devart adlı firmanın dotConnect for MySQL adlı ürününü kullanıyorum. Veri tabanındaki her bir entity’i bir sınıf olarak değil bir EntityObject olarak implement ediyor, bu nedenle her bir entity aynı zamanda Devart’ın ürünü için bir EntityObject anlamına geliyor.

Sizin yapmanız gereken ise T adlı nesnenin bir Class olduğunu belirtmek. EntityFramework’de veri tabanındaki her bir Entity aslı aynı zamanda bir Class’dır.

Repository’imizin interface’i hazır, şimdi gelelim diğer interface’ler için örneğimizi inceleyelim.

Diğer interface’lerimiz de bu şekildedir. IForumDal’ı IEntityRepository’den implement ediyoruz ve parametre olarak bir Entity nesnesi gönderiyoruz. Mantık tamamen bu. Şimdi gelelim concrete sınıflarımızı oluşturalım.

3.Adım Concrete Sınıflarını Oluşturmak

Concrete klasörümüzün içerisi ise bu şekildedir. Adlandırmayı MySQL’e göre yaptığımı belirtmek isterim. Eğer siz Mssql kullanıyorsanız tüm bu sınıflar EntityFramework’un içerisinde olup, adlandırma ise Ef diye başlamalıdır. Örneğin, EfEntityRepositoryBase şeklinde. Şimdi gelin, Repository sııfımızı inceleyelim. En önemli adım burası 🙂

Burada dikkat edilmesi gereken husus ise şudur, EntityObject ve ObjectContext nesneleri MySQL için yazılmıştır. Sırasıyla siz EntityFramework için Class ve DbContext yazmanız gerekmektedir.

Şimdi yukarıdaki kodu inceleyelim. Bu fonksiyon geriye List döndürmektedir. Fonksiyon iki tane parametre alabiliyor, birincisi Linq expression, diğeri ise Lazy Loading için. Yani örnek olarak şöyle; siz Users listesini getirirken örneğin, birde her bir kullanıcıya ait olan Makaleleri getirmek istiyorsanız parametre olarak Makale tablosunun ismini yazmalısınız. Bir detaylı örnek ile bu yapı oturacaktır. Ama önce Business katmanını oluşturmamız ve gerekli Dependency Injection optimizasyonları tamamlamamız gerekmektedir.

4.Adım Business Katmanını Oluşturmak

Business katmanında yine Abstract ve Concrete olmak üzere iki ana klasörümüz olması gerekmektedir. Business katmanında repository’de oluşturduğumuz fonksiyonları, metotları çok kolay bir şekilde kullanacağız. Business katmanında, Service ve Manager olmak üzere 2 ana fonksiyonlarla çalışacağız.

Klasörleme bu şekildedir. Tüm ağır yükleri, hesaplamaları kitaplamayı aslında Business katmanı gerçekleştirir. Siz sadece gerekli controller’dan bu servisleri çağırarak gerekli işlemleri yaparsınız. Örneğin IForumService interface’ini inceleyelim.

Servislerimiz bu şekildedir. Her bir servisin imzaları vardır. Şimdi Concrete klasörünün altında Manager sınıflarımızı inceleyelim. Bu Manager sınıfları gerekli kendilerine ait interface’lerden implement edilecektir, yani servislerden.

ForumManager sınıfımız bu şekildedir. Bizim için önemli olan GetAllLazy adındaki metodumuzdur. Fakat bundan önce şu konudan bahsetmek isterim.

Bu kısım aslında çok şey ifade ediyor. Dependency Injection adını verdiğimi prensibi burada gerçekleştiriyoruz. Constructorda IForumDal’ı set ederek, IForumDal sayesinde repository’e erişim hakkını elde ediyorum. Yani _forumDal. yazdığımızda repository’de ki tüm fonksiyonlara erişiyoruz. Şimdi gelelim GetAllLazy adlı fonksiyonu incelemeye.

_forumDal objesini kullanarak repository’e eriştik. Tüm bu emeklerimizden sonra en kritik yer ise, çağırdığımız fonksiyona parametre olarak ne göndereceğimiz. StringInclude fonksiyonu sadece tablo isimler olarak parametre alacak yani herhangi bir expression almayacak. Yukarıdaki repository kodlarımızdan StringInclude fonksiyonunu inceleyebilirsiniz.

Forum adında bir tablom var ve User,ForumPost ve ForumTopic tablolarıyla ilişkili. Forum listesini çağırdığım zaman aslında her bir foruma ait ForumPostları ve ForumTopicleri gelecektir. ForumPosts.User ise Foruma ait ForumPostlarını oluşturan kişileri çekmek için kullanılır.

Yapı biraz karışık gibi gözüksede aslında basit. Gördüğünüz gibi ihtiyacımız olan tabloları çağırıyoruz. Lazy Loading’i kullansaydık eğer ihtiyacımız olmayan verilerde gelecekti. Buda performans açısından çok ama çok ciddi bir zaafiyet anlamına gelmektedir.

Bu yazı Asp.Net Core MVC, Asp.net MVC, Bilişim, Repository Pattern kategorisine gönderilmiş ve , , , , , ile etiketlenmiş. Kalıcı bağlantıyı yer imlerinize ekleyin.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Alanı Doldurunuz! *