Kurumsal Mimari yapısını anlamak

ESRA ORHAN
5 min readOct 10, 2023

--

Projelerde standart bir alt yapı için , kurumsal gelen yeni bir yazılımcı devam edebilsin diye bir yaklaşım modeli. Bu katmanları bir class library olarak oluşturuyoruz.Bende yeni öğreniyorum ilk başta çok kompleks geliyor.(ağlayasım geldi asdfjdhf tek başına öğrenmek zor)Alıştıkça kolaylaşacağına eminim. Söz uçar yazı kalır. yazarkende pekiştirmek adına sizlerle paylaşmak istedim.

Entities Katmanı

Entity varlık demektir. Genellikle veritabanı nesnelerimizi burda tutarız. Bir tablonun varlıklarını yani classlarımızı burda tutuyoruz. Örneğin iki tablonun bir araya yani join işlemi sonucunda oluşan varlıkları bu katmanda oluşturuyoruz.

DataAccess Katmanı

Bu katmanda veritabanı işlemlerini yaptıgımız katmandır. yani veriye erişim katmanı, Crud(Listeleme , kaydetme , güncelleme, silme) işlemlerinin yapıldığı katmandır. bu katmanda ekstra bişey yazılmıyor. Kural şu; bu kısımda ne bir log kaydı veya if şart belirtilmez. sadece Crud işlemleri yapılır. Bu katmanda bir teknoloji kullanılır entitiyframework, ado net gibi bu kısıma bir şart yazmanız gerekiyor mesela, teknolojiyi değiştirmeniz gerektiğinde aynı kuralları buraya da eklemeniz gerekecek. o yüzden bu tür işlemleri business katmanında yazılmalı.

Business Katmanı

Business iş demektir. Yani burda iş kurallarını burada yazmamız gerekir.Örneğin Crud işlemlerin dısında ekstra bir iş yükü eklemeniz gerektiğinde bu katmanda yazıyoruz. Validasyon, kullanıcı mesajları gibi.

Core Katmanı (Çekirdek Katmanı)

Bu katmanı oluşturduğumuzda bu kütüphaneyi alıp X bir yerde de kullanmamıza olanak sağlıyor. Hiç bir şekilde veri tabanına bağlı olmayan ama veri tabanını kullanacağı şekilde tasarladığımız bir kütüphane. Bir nevi framework katmanıdır. Örneğin JWT işlemleri gibi her projede lazım ortak şeyleri bu katmanda yazıyoruz.

API KATMANI

Bu katman da eğer hem mobil hem de web tarafını geliştirmek istiyorsak bu katmanda lazım olan aksiyonları yazıyoruz. Örneğin bir web sitesini angular, react gibi teknolojilerle geliştirmek istersek bu katmanı yazıyoruz.

Bu kurumsal mimariyi anlamak için temel olarak bir geliştirme tecrübesine sahip olmak gerekiyor.

Uygulamaya başlayalım.

Bu kısıma olan katmanlar da ikişer klasör oluşturuyoruz.

Abstract Klasör : soyut elamanları içerecek. Örneğin interface.

Concrete Klasörü : Somut elemanları içerecek.

Şimdi gelin bir örnek üzerinden devam edelim. Hemen Şuraya bir product class için nasıl yol izliyoruz ona bakalım.

Entities Katmanımda klasörlerimi(Abstract ve Concrete) açtım. Concrete Somut nesneler tuttuğu için concrete sınıfına bir class yapısı oluşturdum.

public class Product :IEntity //veritabanı nesnesidir.
{
public int ProductId { get; set; }
public int CategoryId { get; set; }

public string ProductName { get; set; }
public string QuantityPerUnit { get; set; }
public short UnitsInStock { get; set; }
public decimal UnitPrice { get; set; }
}

IEntity ile imza bırakıyorum. IEntity amacı ilerleyen zamanlarda kısıtlamak için. IEntity bir veritabanı nesnesi oldugunu anlatıyor bunu hangi katmana ekleyeceğiz Tabiki çekirdek yani core katmanına.

Core katmanına gelip o katman için Entities klasörü ekliyoruz. Bu klasörün içine bir interface ekliyoruz. Adı :IEntity

 public interface IEntity // veritabanı nesnelerini imzalamak amaçlı 
{
}

DataAccess katmanına da klasörlerimizi açtık. Abstract kalsörümüze IProductDal interface oluşturduk. bu interface crud işlemlerini product için yazabilirdik. fakat bunu yeni bir class yapısı geldikçe tekrar edeceğinden bunu generic hale getirmemiz şart olacak.O yüzden bu işlemi de Core katmanına taşıyacağız.

Core katmanına DataAccess katmanına hizmet etmesi için DataAccess Adında bir klasör açıyoruz ve içine bir interface oluşturuyoruz. Ve adı IEntityRepository olacak.

public interface IEntityRepository<T> where T :class,IEntity,new()
{
//T Referans tip olmalı bir class olmasına gerek yok bir interface de gönderilebilir T yerine
//kısıt olarak gönderilen nesne new lenebilir olması gerekir demektir.
T GET(Expression<Func<T,bool>> filter); //şarta göre bir nesne getirecek.
List<T> GETLIST(Expression<Func<T, bool>> filter = null); //C# Delege Kullanımı
void ADD(T entity);
void UPDATE(T entity);
void DELETE(T entity);
}

Referans olan ,IEntity implemente edilen , newlenebilir herşeyi gönderebilirsin demektir.

Artık DataAccess.Abstract katmanına gelip IproductDal implemente edebiliriz.

public interface IProductDal : IEntityRepository<Product>
{
// artık IEntityRepository içinde yer alan Crud işlemlerinin hepsi var anlamına geliyor.
}

Artık IEntityRepository içinde yer alan Crud işlemlerinin hepsi var anlamına geliyor.

Context nesnesinin kodlanması

DataAccess katmanında Concrete klasörüne hangi teknolojiyle çalışırsak ona göre klasör açmak gerekirmiş. o yüzden DataAccess>Concrete>EntityFramework şeklinde klasör açıyoruz. ve NorthwindContext adında bir class açıyoruz. Veri tabanıyla iletişim kurmaya yarayacak olan nesnedir.

DataAccess katmanına sağ tıklayıp Manage Nuget Package ile ilgili frameworklerimizi kütüphaneye entegre ediyoruz.

ilgili kütüphanelerimizi indirdikten sonra Context sınıfımızı kodlayalım.

    public class NorthwindContext :DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=SERVERNAME;Database=Northwind;User Id=sa;Password=123;");
}
public DbSet<Product> Products { get; set; }
}

Repository Base Nesnesinin Yazılması

Core katmanından dataaccess kullanacağımız için genel kurallarımızı yazıyoruz. Klasör yapısı şöyle Core>DataAccess>EntityFramework bu klasörün içerisine bir class açıyoruz. Adı : EfEntityRepositoryBase bu sınıfımıza genel bir yapıyı kuracağız. Hemen bu kısıma kodları bırakıyorum. sonrasında açıklamaları hakkı da konuşalım.

  public class EfEntityRepositoryBase<TEntity, TContext> : IEntityRepository<TEntity>
where TEntity : class, IEntity, new()
where TContext : DbContext, new()
{

//TEntity bir referans tiptir.
public void ADD(TEntity entity)
{
using (TContext context = new TContext())
{
var addedEntity = context.Entry(entity);
addedEntity.State = EntityState.Added;
context.SaveChanges();
}
}
}

EfEntityRepositoryBase<TEntity, TContext> bu kısımda TEntity ne veririsek o propertylerle çalışacak. TEntity bir referans tiptir. sonrasında gelen : IEntityRepository<TEntity> bu kısımda üst kısımlarda bahsettiğim interface kullanacak.hatırlarsanız orda kullanması gereken metotları yazmıştık ve Crud işlemlerimiz vardı kalıtım sayesinde artık EfEntityRepositoryBase classımız bu Crud işlemlerine sahip.

where TEntity : class, IEntity, new() bu kısımda da gelen Entitieslere kural tanımlıyoruz gelen veri bir class olmalı,IEntity içermeli ve newlenebilir olmalı.

where TContext : DbContext, new() bu kısımda ise gelen DbContext yapısı içermeli ve newlenebilir olmalı.

İş Katmanında Kodlayalım.

Business katmanında yine Abstract ve Concrete klasörlerimizi açıyoruz. Abstrac Klasöründe product class için IProductService adında bir interface oluşturuyoruz.

 public interface IProductService
{
List<Product> GetList();
Product GetById(int categoryId);
Update(Product product);
Add(Product product);
Delete(Product product);
}

Concrete klasöründe ise class açıyoruz ve ismi ProductManager ve yazdığımız servisten kalıtım olarak yazdığımız metotları almış olacağız.

 public class ProductManager : IProductService
{


private IProductDal _productDal; //Dependency İnjection yapısı

public ProductManager(IProductDal productDal)
{
_productDal = productDal;
}
public List<Product> GetAll()
{
return _productDal.GetList();
}

public List<Product> GetByCategory(int categoryId)
{
return _productDal.GetList(p =>p.CategoryId ==categoryId);
}

public Product GetById(int productId)
{
var x = _productDal.Get(p => p.ProductId == productId);
return x;
}
}

işteee bu kadar. yanlışlarım olmuş olabilir sürçü lisan ettiysek affola. bu katmanlı mimarı yazısını yazabilmek için çok debelendim ama anladım. Güzel kaynak önerilerine açığım. kendinize çok iyi bakın :)

--

--