Mini Dükkan Projesi Ders 003 Repository İşlemleri

Şimdiki adımımız repository oluşturma. Repository çok yaygın bir şekilde kullanılır ve dbcontext sınıfı tarafından sunulan özelliklere erişmek için tutarlı bir yol sağlar. Bazı geliştiriciler repository kullanmayı çok tercih etmezler ama ben önermekteyim, böylelikle veritabanı üzerinde işlemler tutarlı bir şekilde gerçekleştiriliyor ve yinelemelerin önüne geçilebiliyor.

Dersin video eğitim kaydı:

Models klasörüme IDukkanRepository adında bir Interface ekliyorum. Kodlarımı yazıyorum.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MiniDukkan.Models
{
    public interface IDukkanRepository
    {
        IQueryable< Urun > Urunler { get; }
    }
}

Burada bir dizi ürün nesnesi elde ebebilmek için IQueryable kullandım. IQueryable Interface’i; IEnumarable interface’inden türetilmiştir ve IEnumarable gibi sorgulanabilen nesnelerin bir koleksiyonunu temsil eder, bir veritabanı tarafından yönetilir.

IUrunRepository interfaceine bağlı bir sınıf Urun nesnelerine, bu nesnelerin nasıl depolandığını bilmesine gerek kalmadan erişebilir. 

Neden IEnumarable değil, IQueryable Interface Kullanıyoruz?

IQueryable interface’i bir nesne koleksiyonunun verimli bir şekilde sorgulanmasına izin verdiği için çok kullanışlıdır. Örneğimizde bizde veritabanından Ürün nesnesinin alt kümelerini almak için IQueryable kullanacağım. IQueryable interface’i sayesinde veritabanından sadece gereksinim duyduğum nesneleri standart LINQ sorguları ile çekebilirim. Buarada veritabanı sunucusunun verileri nasıl depoladığını veya sorgumu nasıl işlediği beni ilgilendirmiyor. IQueryable interface’i olmasa ben ürün nesnesine dait tüm dataları çekerim ve çektiğim veriler içinde istemediklerimi ayıklamak zorunda kalırdım. Bu da gereksiz yere külfet. Bu sefer uygulamam daha çok ihtiyacı olmayan veri kullanır ve hantallaşır. Bu gibi sebeplerden dolayı IQueryable daha tercih edilebilir bir yöntem. Veritabanı repository interface ve classlarında IQueryable, IEnumarable’a nazaran daha tercih edilebilir bir yöntem.

Tabi şöyle bir durum var. IQueryable interface’i kullanılırken dikkatli olunmalıdır çünkü nesnelerin koleksiyonu her numaralandırıldığında, sorgu yeniden değerlendirilecektir, bu da veritabanına yeni bir sorgu gönderileceği anlamına gelmektedir. Bu durumda verimliliği azaltabilir. Bu gibi durumlarda IQueryable interface’ini ToList ve ToArray extension metotlarını kullanarak daha öngörülebilir bir forma dönüştürebiliriz.

Projemize tekrar dönersek; Repository arayüzünün uygulamasını oluşturmak için Models klasörüme EFDukkanRepository adında bir class ekliyorum. Kodlarımı aşağıdaki şekilde yazıyorum:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MiniDukkan.Models
{
    public class EFDukkanRepository : IDukkanRepository
    {
        private MiniDukkanContext context;

        public EFDukkanRepository(MiniDukkanContext ctx)
        {
            context = ctx;
        }

        public IQueryable< Urun > Urunler => context.Urunler;
    }
}

Burada şu anda repository uygulaması ile IDukkanRepository interface’i tarafından tanımlanmış Urunler property’si ile MiniDukkanContext tarafından tanımlanmış Urunler property’si eşleştirilmektedir. Uygulama geliştirildikçe ek özellikleri de ekleyeceğim.

Context classımdaki Urunler property’si IQueryable interface’ini uygulayan bir DbSet< Urun > döndürmektedir. Böylelikle Entity Framework Core kullanılırken repository interface’ini uygulamayı kolaylaştırmaktadır.

Daha önce söylediğim gibi ASP.NET Core’da nesnelere erişimin tamamına erişebilmek için kullanılan servisler desteklenmektedir. Servislerin bir avantajı hangi uygulama sınıfının olduğunu bilmelerine gerek kalmadan interfaceleri kullanmalarına izin vermeleridir. Bizim bu örneğimizde de EFDukkanRepository uygulama classının olduğunu bilmeden, IDukkanRepository interface’i ile nesnelere erişebiliyoruz.

Şimdi IDukkanRepository için, EFDukkanRepository uygulama classını kullanarak bir servis oluşturmak için Startup.cs classımı aşağıdaki gibi düzenliyorum.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MiniDukkan.Models;

namespace MiniDukkan
{
    public class Startup
    {
        public Startup(IConfiguration config)
        {
            Configuration = config;
        }

        public IConfiguration Configuration { get; set; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddDbContext< MiniDukkanContext >(opts => opts.UseSqlServer(Configuration["ConnectionStrings:MiniDukkanConnection"]));

            services.AddScoped< IDukkanRepository, EFDukkanRepository >();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseStaticFiles();

            app.UseRouting();

            app.UseStatusCodePages();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

Burada kullanılan AddScoped metodu her http isteğinin kendi repository nesnesini aldığı bir servis oluşturur. Bu mantık Entiy Framework Core tarafından da kullanılır.

Bir sonraki derste görüşmek üzere.

Bir cevap yazın

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