.NET Core ile Çok Katmanlı Yapı ve Veri tabanı Entegrasyonu
Herkese merhaba , ben Veysel. Bugün .NET ile Çok Katmanlı Mimari ve basit bir örnekle bu yapının veri tabanı entegrasyonu ile bir MVC projesiyle bağlanmasını sağlayacağız.
Öncelikle kısaca Çok Katmanlı Mimari’nin ne olduğuna bakalım.
Çok Katmanlı Mimarilerde temel olarak 3 katman yer alır ;
Data Access Katmanı
Bu katmanda veri tabanına bağlanmak için context sınıfımız ve ekleme, güncelleme, silme, veri çekme ile ilgili kodlar yazılır. Aynı zamanda Dto işlemleri de bu katmanda yapılır.
Not : Data Access katmanı hiçbir şekilde UI katmanı ile ilişki kuramaz ve veri alışverişi yapamaz. İsterseniz yaparsınız ama SOLID kurallarını gözetmek adına yapmayın :)
Business Katmanı
İş kodlarımızın ve kurallarımızın yazıldığı katmandır. Program UI kısmının veri tabanı isteklerini(request) karşılamadan önce bu katmandaki iş kurallarından geçmelidir. Aynı zamanda encryption(şifreleme) işlemleri ve yetki işlemleri de bu katmanda yapılır. Örneğin sadece admin yetkisine sahip kullanıcıların ürün ekleme sayfasına erişebilmesini istiyorsanız işlemler bu katmanda gerçekleştirilir. Business katmanı Data Access katmanına erişebilir.
UI/API Katmanı
Kullanıcı ile etkileşime geçilen katmandır. Burası bir Form uygulaması, Web sayfası veya bir Console uygulaması olabilir. Temel olarak Get ve Post işlemleri ile veri alışverişi yapılır. Kısaca Model ve View arasındaki geçiş katmanı olarak nitelendirilir.
Temel olarak üç katmandan bahsettik. Bunlara ek(projeden projeye değişebilir) olarak iki katmanımız daha var.
Entity Katmanı
Bu katmanda veri tabanı tablolarımıza karşılık gelen classları tutarız. Bazı durumlarda Dto oluşturmamız gerekir. Dto kısaca iki ve üstü veri tabanı tablosundaki istenilen alanları birleştirmeye yarayan classlardır. Birleştirme işlemi Data Accessde yapılır.
Core Katmanı
Farklı projelerde kendimizi tekrar etmemek için , birçok projede ortak olan kodların, sınıfların, işlemlerin yapıldığı katmana Core katmanı denir. Dikkat edilmesi gereken şey bu katmanın diğer katmanlara bağımlılığının olmamasıdır. Çünkü bunu her projede kullanmak istiyoruz.
Evet çok katmanlı yapıyı açıkladığımıza göre projemize geçebiliriz.
İlk önce Alttaki linkten Northwind veri tabanı scripti ile veritabanını oluşturmanız gerekmekte. İçinden çıkan script dosyasını Sql Management Studio ile veya Visual Studio’da Sql Server Object Explorer ile açıp çalıştırın.
http://binaryworld.net/blogs/wp-content/uploads/2014/03/Insta<<ll-Northwind-Script.zip
Sonrasında ASP.NET Core Web App projesi açalım.
Katmanlarımızdan bahsetmiştik. Her katmanı oluşturalım ve içerisini resimdeki gibi dosyalayalım.
Abstract: Soyut sınıfların tutulduğu kısımdır.
Concrete: Somut sınıfların tutulduğu kısımdır.
Entity/Concrete içerisinde veri tabanı tablosu ile ilişkili olacak classı oluşturduk.
Core/Entities içerisine IEntity adlı bir interface oluşturduk. Product sınıfımızın bunu implemente etmesini istiyoruz. Somut sınıflarımızla ilerde soyutlamayla ilgili sorunlar yaşamamak için bu şekilde bir soyut IEntity interface’i oluşturduk.
Core katmanına gelmişken Core/DataAccess içerisine IRepository interfaceini oluşturalım. Bu interfacein görevi temel bir CRUD işlemleri yapısı oluşturmak.
Kodlara gelirsek IEntityRepostiory<T> kısmındaki T bir classa karşılık geliyor. where T kısmından sonra kurallarımızı sıraladık.
T bir class olmalı , bu class IEntity türünde olmalı ve programlayan kişi T kısmına direk IEntity interface’ini vermesin diye newlenebilir olmalı dedik. Çünkü interfaceler newlenemez.
İçerisine gelirsek CRUD operasyonları için methodlarımızı oluşturduk , hepsi T türünde değer döndüğü için kod tekrarına düşmeden çok kolay bir şekilde işlemleri yapabileceğiz.
Core/EntityFramework klasörünün içerisine EfEntityRepositoryBase sınıfı oluşturduk. Bu sınıf IEntityRepository sınıfını implemente ediyor. Burada methodların içini doldurduk. Eğer EF’den başka bir araca geçmek istersek diğer araç içinde böyle bir sınıf oluşturmamız yeterli olur.
Data Access/Concrete içerisine DemoContext adında bir class oluşturduk. Bu classın görevi veri tabanı bağlanma stringini oluşturmak ve tablo ilişkilendirmelerinin yapılması. \mssqllocaldb kısmından önceki kısım değişiklik gösterebilir.
Not : Bu aşamada Microsoft.EntityFrameworkCore ve Microsoft.EntityFrameworkCore.Sql paketini indirmemiz gerekiyor. Bunun için solution üstünde sağ tıklayıp : Manage Nuget Packages → Browse → Microsoft.EntityFrameworkCore.SqlServer yazıp Core ve Data Access sınıfına ekliyoruz.
DataAccess/Abstract içerisine IProductDal isimli interface oluşturduk ve bu interface IEntityRepository<Product>’i implemente ediyor. T olarak da Product için oluşturduğumuzdan Product sınıfını verdik.
DataAccess/Concrete içerisine EfProductDal isimli sınıf oluştuyoruz. Bu sınıfta EfEntityRepository sınıfını implemente ediyor. TEntity olarak Product ve Context olarak DemoContext sınıfımızı parametre olarak verdik. Bu sınıf aynı zamanda IProductDalı implemente ediyor.
Ve geldik Business katmanına. Bu katmanda iş kurallarımızı yazdığımızı söylemiştik. Öncelikle Abstract klasörü içine IProductService adlı class oluşturuyoruz. Konu uzamasın diye bir get ve bir post işlemi yapacağız. Bu yüzden Product listesi döndürecek GetAll() methodu ve geri değer döndürmeyecek Add() methodu tanımlaması yaptık. Add methodu parametre olarak Product alıyor.
Ve geldik somut sınıfımız olan ProductManager sınıfına. Bu sınıf IProductService’i implemente ediyor dolayısıyla içindeki methodlar gelmiş oldu. Burada ProductManagerın constructorına IProductDalı parametre olarak verdik ve birbirine eşitledik. Kısaca Dependecy Incection ile gevşek bağımlılık oluşturduk.
Add methodunda _productDal’dan gelen Add() methodunu kullandık
GetAll() methodunda aynı yerden gelen GetAll() methodunu kullandık ve return ettik.
Son katmanımız olan UI kısmında Controllers üstüne sağ tıklayıp Add → Controller dedikten sonra Controller-Empty seçeneğini seçiyoruz. İsmini ProductController verip kaydediyoruz. Constructor ile Dependecy Injection yapıyouz. GetAll() ve Add() methodlarını tanımlıyoruz ve methodların üstünde sağ tık yaparak add View diyoruz. Views Klasöründe viewler gelmiş olmalı.
Öncelikle bütün ürünleri getireceğimiz sayfanın düzenini belirleyelim. Bu projede BootStrap kullanıldığı için wwwroot →lib →bootstrap →dist →css altındaki bootstrap.css dosyasını GetAll.cshtml sayfası içine sürüklüyoruz.
“@ işareti ile başlayan kısımlar razor yapısıdır.”
Add.cshtml sayfasında ise ekleme işlemi yapacağız. Burada bir model göndermiyoruz. Önemli olan kısım inputların name alanının Product nesnenizle aynı isimde olması ve type kısmının da doğru veri türünde olmasıdır.
Form tagına method=”post” vermeyi ve tagın içine Add butonu eklemeyi unutmayın. Geri kalan kısımlar tasarım ile ilgili.
Son olarak api katmanı üzerine sağ tıklayıp Set as Startup Project seçeneğine tıklayıp projeyi ayağa kaldıralım. Tarayıcının url kısmına https://localhost:Port Adresi/Product/GetAll yazalım ve şöyle bir hata alalım :) ;
Bu hatanın sebebi controllerdaki IProductService Injectionı. Program burada ProductController örneği oluşturmaya çalıştığını ama IProductService örneği oluşturamadığından yapıcı bloğu geçemediğini söylüyor.
Yapmamız gereken startup.cs içerisine gelip IProductService gönderilirse ne verileceğini ve IProductDal gönderilirse ne verileceğini belirtiyoruz.
Projeyi tekrar ayağa kaldırdığımızda program çalışacaktır. Burada Product bilgilerini listeledik.
Add product butonuna tıklayınca bizi Add sayfasına yönlendirdi. Burada değerleri girip Add diyoruz
Tablonun sonuna Deneme adlı ürün eklendi.
Evet bugünkü yazı bu kadardı biraz uzun oldu ama anlaşılır olmuştur. Okuduğunuz için teşekkür ederim.