Çok katmanlı mimari, güçlü ve kolay geliştirelebilen ve katmanlarının kolaylıkla değiştirilebilen büyük uygulamalarda çok önemli bir rol oynar.
Eski ve en ünlü çok katmanlı mimari, 3 katmandan oluşmakta
Onion Architecture veya Soğan mimarisi Jeffrey Palermo tarafından onerilmiştir. bu mimaride her katman soğan halkaları gibi düşünülmüş olup kolaylıkla değiştirilebilmesi veya düzenlenmesi amaçlanmıştır. bu mimariyi Repository Pattern ile düşündüğümüzde, bu işlem daha da kolay bir hal alıyor.
Soğan mimarisinde temel kural şöyledir: her üst düzey katman daha merkezi katmanlara bağlıdır, ancak merkezi katmanlar ondan sonrakilere bağlı olamaz. yani her hangi katmanda yapılan değişiklikler merkeze doğru olan katmanları etkilemez ancak ondan sonraki katmanları etkileyebilir. Burada dikkat edilmesi gereken nokta, harici katmanların iç katmanların hepsine bağlı olma zorunluluğu yoktur. örneğin "Data Access" Katmanı "Application Services" katmanını atlayabilir.
Bu Mimaride geleneksel mimarinin aksine veri katmanı en iç katman olarak değil, en dış katman olarak belirlenmiş, böylece uygulamada verinin nerden geldiğinden bağımsız olarak bir uygulama geliştirilebilir. Ayrıca en dış katmanlardan diğeri Test Katmanıdır, ki uygulamanın testlerini uygulamanın diğer katmanlarından bağımsız kılıyor. bir diğer dış katman ise Kullanıcı arayüzüdür. bu sayede bir uygulama çekirdeği için farklı arayüzler tasarlanabilir. ister theme olarak düşünün, ister aynı uygulamanın mobil arayüzü ve web arayüzü olarak düşünün.
Jeffrey Palermo'nun Soğan mimarisini, C# ve Asp.net Mvc'de repository pattern kullanarak bir taslak hazırladım, aşağıda bu taslağın ve genel olarak yeni bir uygulamaya başladığınızda (enterprise uygulama) adım adım nasıl oluşturulabileceğini okuyabilirsiniz.
Taslağın kaynak kodlarına bu linkten ulaşabilirsiniz: https://github.com/mesuttalebi/NTierCSharpExample
1- Projeleri oluştur
Öncelikle boş bir "solution" oluşturunuz. ilk olarak "kullanıcı arayüzü katmanı" için bir "console application" projesi veya asp.net mvc projesi ekleyiniz ve projenin adını "multilayer.presentation" olarak seçiniz. Bu ismi istediğiniz isimle değiştirebilirsiniz ancak genel olarak bir solution'daki tüm projeleri belirli bir namespace'le başlamanız önerilir, bu namespace proje ismi olabilir. örneğin eticaret bir proje geliştiriyorsanız proje ismini "eticaret.presentation" seçebilirsiniz.
bu proje de (Kullanıcı arayüzü katmanı) kullanıcı arayüzünü geliştireceksiniz.
ikinci üçüncü ve dördüncü projeleri "class library" olarak ekleyiniz ve isimlerini "Domain Katmanı" için"multilayer.domain", "veri katmanı" için "multilayer.infrastructure" ve "İş modeli katmanı" için "multilayer.services" olarak adlandırınız.
birinci aşamanın sonunda solution explorer aşağıdaki şekilde olmalıdır.
Her proje neleri kapsiyor?
"multilayer.domain" projesinde "object" klaslarını tutacağız. (Blog, Author, ...).
bu proje soğan mimarisindeki "Domain Model" katmanını kapsıyor.
"multilayer.services" projesinde "iş model katmanı" olarak kullanıyoruz ve soğan mimarisindeki "Application Services" katmanını kapsıyor.
"multilayer.infrastructure" projesi ise, "Data Access katmanı"nı kapsıyor ve repository klaslarımızı burada tutacağız.
2- Bağlantılar (References)
Soğan mimarisine göre bağlantılarda en merkezi katman olan "Domain Katmanı" (Object klasları) hiç bir katmana bağlı olmaması lazım. yani "multilayer.domain" diğer hiç bir projeye bağlı değil ve herhangi bir reference eklemeniz gerekmiyor.
"multilayer.infrastructure" projesinden "multilayer.domian" projesine referance ekleyiniz. ("multilayer.domian" aslında aynı zamanda "domain services" katmanının yerinede geçiyor, şöyle ki domain interface'lerimizi aynı proje içinde başka bir klasörde saklıyoruz, ve domain klaslarıyla iletişim sadece ve sadece interface'ler aracılığıyla yapılıyor.
"multilayer.services" projesinden "multilayer.domain" ve "multilayer.infrastructure" projesine reference ekleyiniz. bu proje "Application Services" Katmanı olarak kullanılıyor.
Burada "multilayer.infrastructure" projesine bağlantıya sadece "Dependency Injection" için ihtiyacımız var.
"mutlilayer.presentation" projesinden ise "multilayer.domain", "multilayer.services" projesine link veriniz.
Dikkat: bu projede "Data Access" Katmanı için Entity Framework kullanılıyor.
Diğer Bağlantılar:
Dependency Injection için bu projede ninject kullanılmış. nuget kullanarak ninject'i indiriniz ve "multilayer.presentation" ve "multilayer.services" projelerine ekleyiniz.
Bu yazı Devam edecek.
Lütfen detaylar için projenin kaynak kodlarını Buradan indiriniz. sorularınızı yorumlar kısmından bana yöneltebilirsiniz.
Güncelleme: 23.10.2016
Devam:
Nininject Ayarlaması
Daha önce belirttiğimiz gibi, presentation katmanından hiç bir şekilde Infrastructure (DAL) katmanına referans eklemiyoruz ve presentation katmanından veri ekleme güncelleme ve genel olarak veritabanı ile ilgili olan tüm işlerimizi Business (BLL - Multilayer.Services) katmanı aracılığıyla yapacağız.
Proje içinde objelerin birbirine bağlılığını ortadan kaldırmak amacıyla ve SOLID'in son prensipi olan Dependency Inversion'a uymak için IoC kavramına göre kod geliştiriyoruz ve bunun içinde bağımlılığı dışarıdan enjekte etmek gerekmektedir. (Dependency Injection- DI).
bağımlılığı dışarıdan enjekte edebilmek için DI Container(Bağımlılık Kabı) dediğimiz bir eklentiye ihtiyacimiz vardır. en ünlü hazır DI Container'lardan Autofac ve Ninject söylenebilir. ben projede Ninject kullanıyorum, özel bir sebebi yoktur sadece alışkanlık.
Ninject'i iki projemizde kullanacağız. birincisi presentation katmanı, ikincisi ise, Business katmanı. presentation katmanında business service'lerime ait objelerin presentation da kullanıldığı yerlerde enjekte etmek için kullanacağız. business katmanında ise, infrastructure objelerini business'de kullandığımız yerlere enjekte etmek için ihtiyacımız var.
Business katmanı projesine sadece Ninject kurmanız yeterlidir, Presentation katmanında ise Ninject.MVC5 kurunuz, diğer eklentilerini otomatik kuracaktır.
(DİKKAT: DI Container'ı kendimiz de geliştirebiliriz. ancak konudan uzak olduğu için burada yer vermiyorum).
Ninject'e hangi interface kullanıldığı zaman hangi objeyi oluşturup göndermesi gerektiğini söylemek işlemine Binding denilir. bu binding işlemlerini presentation da Ninjectwebcommon.cs dosyasında yapacağız. business'te ise yeni bir class oluşturup onun içinde tanımlayacağız.
presentation katmanında, ninject kurulduğunda, App_Start klasörü içine NinjectWebCommon.cs dosyasını oluşturmaktadır.
Binding'lerimizi "RegisterServices" fonksiyonu içine yazacağız.
Örnek:
yukarıdaki kodda, aslında şunu söylüyoruz, ne zaman ki IBlogService türünden bir objeye ihtiyacım olsa, BlogService türünden bir obje oluşturup bana döndür.
Yukarıdaki resimde gördüğünüz üzere, binding işlemlerini yapmadan önce, business katmanındaki bindingleri ninject kerneline yüklemesini söylemişim. Services.DIModule aslında business katmanın ninject modul'udur.
business katmanında aşağıdaki resimde görüldüğü gibi bir class oluşturup NinjectModule klasından kalıtım alıyoruz, bu klas içinde ise NinjectModule'un Load fonksiyonunu override (geçersiz kılmak) ederek business tarafı binding'lerimizi içine yazıyoruz.
DIModule aşağıdaki gibidir:
Bağımlılıkların enjekte edilme işlemi de tamamlanmış oldu. geriye tek şey kaldı, bu bağımlılıklar nasıl kullanılcak.
bağımlılıklar presentation tarafında da, business tarafında da class'ların constructor fonksiyonlarına parametre olarak gönderiliyor. örneğin: BlogController'da BlogService ile iletişim kurabilmek için, BlogController class'ının Constructor fonksiyonuna IBlogService parametresini ekliyoruz.
Yukarıda gördüğünüz üzere, controller içinde kullanabilmek için IBlogService türünden bir private değişken tanımlanmıştır ve bu değişken Constructor vasıtasıyla gelen yine aynı türden olan bir değişken ile initialize ediliyor. Constructor'daki IBlogService'inin doldurulma görevi Ninject'e bırakılmıştır. ve tanımladığımız binding'ler ile Ninject, IBlogService gördüğü zaman hangi objeden oluşturup doldurması gerektiğini biliyor.
BlogService Class'ında ise Constructor IRepository<Blog>() türünden bir değişken beklemektedir. Ninject, business katmanındaki tanımladığımız DIModule classındaki binding'lere bakarak hangi obje ile doldurması gerektiğini bilmektedir.
Böylece Presentation katmanından Infrastructure (DAL) katmanına hiç bir şekilde referans eklemeden sadece Business katmanı aracılığıyla ulaşabilmekteyiz.
Bir sonraki makalemde, Soğan mimarisine göre oluşturulan bir projede Asp.Net Identity kullanımını göstereceğim.
Eski ve en ünlü çok katmanlı mimari, 3 katmandan oluşmakta
- Data Access Layer - Veri Katmanı
- Business Process Layer - İş Modeli Katmanı
- Presentation Layer - Kullanıcı Arayüzü Katmanı
Geleneksel Katmanlı Mimari |
Soğan mimarisinde temel kural şöyledir: her üst düzey katman daha merkezi katmanlara bağlıdır, ancak merkezi katmanlar ondan sonrakilere bağlı olamaz. yani her hangi katmanda yapılan değişiklikler merkeze doğru olan katmanları etkilemez ancak ondan sonraki katmanları etkileyebilir. Burada dikkat edilmesi gereken nokta, harici katmanların iç katmanların hepsine bağlı olma zorunluluğu yoktur. örneğin "Data Access" Katmanı "Application Services" katmanını atlayabilir.
Soğan Mimarisi Şeması |
Jeffrey Palermo'nun Soğan mimarisini, C# ve Asp.net Mvc'de repository pattern kullanarak bir taslak hazırladım, aşağıda bu taslağın ve genel olarak yeni bir uygulamaya başladığınızda (enterprise uygulama) adım adım nasıl oluşturulabileceğini okuyabilirsiniz.
Taslağın kaynak kodlarına bu linkten ulaşabilirsiniz: https://github.com/mesuttalebi/NTierCSharpExample
1- Projeleri oluştur
Öncelikle boş bir "solution" oluşturunuz. ilk olarak "kullanıcı arayüzü katmanı" için bir "console application" projesi veya asp.net mvc projesi ekleyiniz ve projenin adını "multilayer.presentation" olarak seçiniz. Bu ismi istediğiniz isimle değiştirebilirsiniz ancak genel olarak bir solution'daki tüm projeleri belirli bir namespace'le başlamanız önerilir, bu namespace proje ismi olabilir. örneğin eticaret bir proje geliştiriyorsanız proje ismini "eticaret.presentation" seçebilirsiniz.
bu proje de (Kullanıcı arayüzü katmanı) kullanıcı arayüzünü geliştireceksiniz.
ikinci üçüncü ve dördüncü projeleri "class library" olarak ekleyiniz ve isimlerini "Domain Katmanı" için"multilayer.domain", "veri katmanı" için "multilayer.infrastructure" ve "İş modeli katmanı" için "multilayer.services" olarak adlandırınız.
birinci aşamanın sonunda solution explorer aşağıdaki şekilde olmalıdır.
Solution Explorer |
"multilayer.domain" projesinde "object" klaslarını tutacağız. (Blog, Author, ...).
bu proje soğan mimarisindeki "Domain Model" katmanını kapsıyor.
"multilayer.services" projesinde "iş model katmanı" olarak kullanıyoruz ve soğan mimarisindeki "Application Services" katmanını kapsıyor.
"multilayer.infrastructure" projesi ise, "Data Access katmanı"nı kapsıyor ve repository klaslarımızı burada tutacağız.
2- Bağlantılar (References)
Soğan mimarisine göre bağlantılarda en merkezi katman olan "Domain Katmanı" (Object klasları) hiç bir katmana bağlı olmaması lazım. yani "multilayer.domain" diğer hiç bir projeye bağlı değil ve herhangi bir reference eklemeniz gerekmiyor.
"multilayer.infrastructure" projesinden "multilayer.domian" projesine referance ekleyiniz. ("multilayer.domian" aslında aynı zamanda "domain services" katmanının yerinede geçiyor, şöyle ki domain interface'lerimizi aynı proje içinde başka bir klasörde saklıyoruz, ve domain klaslarıyla iletişim sadece ve sadece interface'ler aracılığıyla yapılıyor.
"multilayer.services" projesinden "multilayer.domain" ve "multilayer.infrastructure" projesine reference ekleyiniz. bu proje "Application Services" Katmanı olarak kullanılıyor.
Burada "multilayer.infrastructure" projesine bağlantıya sadece "Dependency Injection" için ihtiyacımız var.
"mutlilayer.presentation" projesinden ise "multilayer.domain", "multilayer.services" projesine link veriniz.
Dikkat: bu projede "Data Access" Katmanı için Entity Framework kullanılıyor.
Diğer Bağlantılar:
Dependency Injection için bu projede ninject kullanılmış. nuget kullanarak ninject'i indiriniz ve "multilayer.presentation" ve "multilayer.services" projelerine ekleyiniz.
Bu yazı Devam edecek.
Lütfen detaylar için projenin kaynak kodlarını Buradan indiriniz. sorularınızı yorumlar kısmından bana yöneltebilirsiniz.
Güncelleme: 23.10.2016
Devam:
Nininject Ayarlaması
Daha önce belirttiğimiz gibi, presentation katmanından hiç bir şekilde Infrastructure (DAL) katmanına referans eklemiyoruz ve presentation katmanından veri ekleme güncelleme ve genel olarak veritabanı ile ilgili olan tüm işlerimizi Business (BLL - Multilayer.Services) katmanı aracılığıyla yapacağız.
Proje içinde objelerin birbirine bağlılığını ortadan kaldırmak amacıyla ve SOLID'in son prensipi olan Dependency Inversion'a uymak için IoC kavramına göre kod geliştiriyoruz ve bunun içinde bağımlılığı dışarıdan enjekte etmek gerekmektedir. (Dependency Injection- DI).
bağımlılığı dışarıdan enjekte edebilmek için DI Container(Bağımlılık Kabı) dediğimiz bir eklentiye ihtiyacimiz vardır. en ünlü hazır DI Container'lardan Autofac ve Ninject söylenebilir. ben projede Ninject kullanıyorum, özel bir sebebi yoktur sadece alışkanlık.
Ninject'i iki projemizde kullanacağız. birincisi presentation katmanı, ikincisi ise, Business katmanı. presentation katmanında business service'lerime ait objelerin presentation da kullanıldığı yerlerde enjekte etmek için kullanacağız. business katmanında ise, infrastructure objelerini business'de kullandığımız yerlere enjekte etmek için ihtiyacımız var.
Business katmanı projesine sadece Ninject kurmanız yeterlidir, Presentation katmanında ise Ninject.MVC5 kurunuz, diğer eklentilerini otomatik kuracaktır.
(DİKKAT: DI Container'ı kendimiz de geliştirebiliriz. ancak konudan uzak olduğu için burada yer vermiyorum).
Ninject'e hangi interface kullanıldığı zaman hangi objeyi oluşturup göndermesi gerektiğini söylemek işlemine Binding denilir. bu binding işlemlerini presentation da Ninjectwebcommon.cs dosyasında yapacağız. business'te ise yeni bir class oluşturup onun içinde tanımlayacağız.
presentation katmanında, ninject kurulduğunda, App_Start klasörü içine NinjectWebCommon.cs dosyasını oluşturmaktadır.
Binding'lerimizi "RegisterServices" fonksiyonu içine yazacağız.
Örnek:
Bind<IBlogservice>().To<BlogSerive>();
yukarıdaki kodda, aslında şunu söylüyoruz, ne zaman ki IBlogService türünden bir objeye ihtiyacım olsa, BlogService türünden bir obje oluşturup bana döndür.
Yukarıdaki resimde gördüğünüz üzere, binding işlemlerini yapmadan önce, business katmanındaki bindingleri ninject kerneline yüklemesini söylemişim. Services.DIModule aslında business katmanın ninject modul'udur.
business katmanında aşağıdaki resimde görüldüğü gibi bir class oluşturup NinjectModule klasından kalıtım alıyoruz, bu klas içinde ise NinjectModule'un Load fonksiyonunu override (geçersiz kılmak) ederek business tarafı binding'lerimizi içine yazıyoruz.
DIModule aşağıdaki gibidir:
using MultiLayer.Domain.Entities; using MultiLayer.Domain.Interfaces; using MultiLayer.Infrasturcture.Repositories; using Ninject.Modules; namespace MultiLayer.Services { public class DIModule : NinjectModule { public override void Load() { Bind<IRepository<Blog>>().To<Repository<Blog>>(); } } }
Bağımlılıkların enjekte edilme işlemi de tamamlanmış oldu. geriye tek şey kaldı, bu bağımlılıklar nasıl kullanılcak.
bağımlılıklar presentation tarafında da, business tarafında da class'ların constructor fonksiyonlarına parametre olarak gönderiliyor. örneğin: BlogController'da BlogService ile iletişim kurabilmek için, BlogController class'ının Constructor fonksiyonuna IBlogService parametresini ekliyoruz.
Yukarıda gördüğünüz üzere, controller içinde kullanabilmek için IBlogService türünden bir private değişken tanımlanmıştır ve bu değişken Constructor vasıtasıyla gelen yine aynı türden olan bir değişken ile initialize ediliyor. Constructor'daki IBlogService'inin doldurulma görevi Ninject'e bırakılmıştır. ve tanımladığımız binding'ler ile Ninject, IBlogService gördüğü zaman hangi objeden oluşturup doldurması gerektiğini biliyor.
BlogService Class'ında ise Constructor IRepository<Blog>() türünden bir değişken beklemektedir. Ninject, business katmanındaki tanımladığımız DIModule classındaki binding'lere bakarak hangi obje ile doldurması gerektiğini bilmektedir.
Böylece Presentation katmanından Infrastructure (DAL) katmanına hiç bir şekilde referans eklemeden sadece Business katmanı aracılığıyla ulaşabilmekteyiz.
Bir sonraki makalemde, Soğan mimarisine göre oluşturulan bir projede Asp.Net Identity kullanımını göstereceğim.
MVC tek başına çok katmanlı bir mimari sayılır mı ? Yoksa soğan veya 3 katmanlı mimari gibi bir yazım şekli belirlemek mi gerekiyor.
YanıtlaSilSayılmaz. MVC'de Seperation of Concerns (SOC) sağlanmaktadır, yani bir koddaki ilgili bölümleri birbirinden ayırmayı sağlanmaktadır, ancak SOC katmanlı mimari demek değildir. Özellikle büyük projelerde katmanlı mimari kullanmak daha doğrudur.
SilMVC tek başına çok katmanlı bir mimari sayılır mı ? Yoksa soğan veya 3 katmanlı mimari gibi bir yazım şekli belirlemek mi gerekiyor.
YanıtlaSilhocam connection stringi nerede belirttiniz ?
YanıtlaSilConnection String, presentation'da web.config'de yer almaktadır.
SilBir sorum daha olacak dbcontext i normalde direk kulanıyorduk ve verileri istediğimiz her katmanda çekebiliyorduk. Örnepin bir partial view de statik bir veriyi db den çekip listeleyebiliyorduk. Peki bu durumda ne yapmamız gerekiyor ? View içerisinde db den veri çağırma işlemini nasıl yapacağız ?
SilView için veritabanına ulaşmak doğrı bir yöntem değil, View'in görevi ona verilen veriyi kullanıcı dostu bir şekilde yorumlamak ve göstermektedir. MVC'de View'e gelen data Model'dir, Model'i için veriyle donatmak görevi ise controller'e aitdir, ancak Katmanlı mimaride Controller'in de doğrudan veritabanına ulaşması yasaktır, bu durumda Controller veriyi Business Katmanından ister, Business Katmanı ise DAL (Infrastructure) dan. en son veritabanına ulaşan ve sorguyu yapan katman DAL katmanıdır. kısaca istek akışı şu şekilde olmalı. PL ==> BLL'den, BLL ==> DAL'dan ve DAL ==> Veritabanından olması lazım.
SilMerhabalar,
YanıtlaSil""mutlilayer.presentation" projesinden ise "multilayer.domain", "multilayer.services" projesine link veriniz." diye söylemişsiniz. burada katettiğiniz referans mı vericez. dll mi ekliycez.
Merhaba, Evet Link'ten kastım, "Referance" eklemektir.
YanıtlaSilHocam merhaba , bu anlattığınız pattern piyasada ne derecede kullanılıyor. Bununla ilgili çok fazla döküman bulamıyorum (türkçe & ingilizce kaynaklar) acaba yaygın değil mi ? Ve onion arch ile identity kullanımını yapacak mısınız ?
YanıtlaSilMerhaba, Eski 3 katmanlı mimariye göre daha güncel bir mimaridir, Yeni olduğu için eskisi kadar yaygın değildir. İngilizce Kaynak bolca vardır diye biliyorum internette, bu linkten mimarin kendi dilinden anlatımını inceleyebilirsiniz. http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
YanıtlaSilIdentity Kullanımını ilk fırsatta yazacağım.
Hocam öncelikle merhabalar anlatımınız için çok teşekkürler. Yaptığınız uygulamayı bende adım adım tekrar ederek yaptım ve mimari konusunda baya katkı sağladı. Yalnız bir sorum olacak konuyla alakalı ama farklı bir bakış açısı MVC mimarisi dediğiniz gibi katmanlı mimari sayılmaz büyük projeler için elbette katmanlı mimari kullanımı çok gerekli özellikle repository ve unit of work yapısının sağlıklı çalışması için fakat MVC de bulunan Contoller ile BLL de gerçekleşek olan işlmeler entity freamwork sayesinde hızlı bir şekilde gerçekleşiyor Entity'lerin olduğu Model Katmanını anlıyorum tamam fakat CRUD işlemleri için MVC projesi için de Repository ve Unit of Work için klasör oluştursak ve BLL katmanına ihtiyac kalmasa mantıklı olmaz mı ? Yani Projede sadece entity'lerin olduğu ClassLibrary projesi olsa ve birde MVC Projesi olsa daha efektif olmaz mı?
YanıtlaSilMerhaba Bora, BLL katmanı Soğan mimarisinde Application Core kısmında kalan bir katmandır.ürünün tüm İş kuralları ve İşin tanımlayan katman aslında BLL katmanıdır. Presentation katmanından doğrudan DAL katmanına referans verilmesi doğru değildir. bunun dışında BLL aynı kalır ama Presentation değişir, örneğin Uygulamana bir mobil ara yüz eklemek istediğin zaman BLL'in değişmeyecektir. aynı BLL yeni presentation için de kullanılacaktır. yanı kısacası dediğiniz senatiyo katmanlı bir mimari olmaz.
SilHocam Merhaba. Bu mimariyi Web API için kullanabiliriz demi. Presantation katmanını mvc değil de api projesi olarak oluşturursak diğer katmanlar aynı kalabilir mi ?
YanıtlaSilMerhaba Aziz, Bu Mimaride WebAPI UI katmanı olarak değil ancak Business Katmanında yeni bir proje olarak ekleyip business katmanının API'si olarak diğer kullanacak Client'lara (Mobil, Angular vs.) sunulabilir.
SilTeşekkürler hocam. Adamsınız
SilMerhaba , makale için teşekkürler. Faydalı bir yazı olmuş fakat kafama takılan bir nokta var. Makalenin başında "merkezi katmanlar ondan sonrakilere bağlı olamaz" demişsiniz. Verilen örnekte ise application service katmanı infrastrcuter katmanına bağlı. Bu sebeple kafam karıştı biraz.
YanıtlaSilOnion Architecture içinde, katmanlar iç içe geçmiş bir yapıya sahiptir ve genellikle dıştaki katmanlar içteki katmanlara bağlıdır, ancak içteki katmanlar dıştaki katmanlara bağımlı değildir. Ancak, iç katmanlardan biri olan uygulama katmanı, veritabanından veri almak veya veritabanına veri kaydetmek gibi işlemler için altyapı katmanına (dış katman) bağımlı olabilir.
SilBu genellikle iç katmanlardaki iş mantığını dış katmanlardan bağımsız tutmak amacıyla yapılır. İç katmanlar genellikle interface'leri veya contract'ları tanımlar ve dış katmanlar, örneğin altyapı katmanı, bu interface'leri uygular. Böylece iç katmanlar, iş mantığını korurken dış sistemlerle etkileşimde bulunabilir.
Bu durumda, uygulama katmanı, veri erişimi gibi konular için interface'leri tanımlar ve altyapı katmanı bu interface'leri uygular. Bu, içteki iş mantığını dıştaki sistemlerden izole etmeye ve esnek bir yapı sağlamaya yardımcı olur.
Bu örneği yıllar önce yapmıştım, hem karmaşık yapmamak için, hem application katmanı istisna olduğu için çok gerek duymamıştım, fakat tamamen izole edelim dersek yukarıda bahsettiğim gibi yapılabilir.