.NET MVC proje mimarisi / katmanlama


11

Orta büyüklükteki bir MVC web uygulaması için mimariyi planlarken, katmanları mümkün olduğunca ayrıştırılmış ve test edilmesi kolay olacak şekilde nasıl uygularsınız? (temel olarak en iyi uygulamaları izleyin) Diyelim ki veri erişimim olarak önce kodu kullanıyorum.

"İş mantığını" neyin tanımlayacağı ve veri katmanıyla etkileşimin nasıl kastedildiğiyle mücadele ediyorum. Bir araç satış uygulamasını örnek olarak ele almak, iş mantığı verilen araçlar için vergi bandını hesaplamak, galon başına mili karşılaştırmak gibi görevleri yerine getiren sınıflar olabilir mi? Ticari kuruluşlara gelince (örneğin Arabalar, Vanlar, Motosikletler) Bunları sınıfımla birlikte veri katmanına koyardım DataContext.

Ayrıca, işin aksine uygulama mantığını ne teşkil eder? Oturum / kullanıcı girişi doğrulamaları gibi şeyleri tahmin ediyorum?

Örneğin, bir araba denetleyicisi türüne ve en iyi mpg'ye göre filtrelenen ilk on arabayı listeleyen bir eylem / görünüm sonucu döndürebilir. Diyelim ki ICarRepositorydenetleyicime bir 'carRepo' enjekte ettim (depo desenini / DI kullanarak), arabamı bir eylem yöntemi parametresinden filtreliyorum;var cars = carRepo.getCarsByType("hatchback");

Bu yüzden veri mantığı bilgisini bir depo kullanarak kontrol cihazımın dışında tuttum, şimdi iş mantığını bir etki alanı modeli kullanarak denetleyiciden uzak tutmak için - var sonuç = yeni MpgCalculator (arabalar); - Diyelim ki hesap makinesi sınıfına ihtiyacım var çünkü en iyi yakıt verimliliğini hesaplamak için ek mantık gerçekleştirmesi gerekiyor. Şimdi, veri erişim katmanından almak için bir havuz kullanılan görünümü için bir veri kümesi var ve bu veriler üzerinde işle ilgili görevleri işlemek ve gerçekleştirmek için etki alanına özgü bir nesne var.

Burada hata mı yapıyorum? veri havuzu modelini kullanmaya ihtiyacımız var mı yoksa ORM'yi ve testi ayırmak için sadece bir arabirime kod yazabilir miyim? Bu konuda, somut veri erişim sınıflarım dbcontext veri katmanında olduğu için, arayüz tanımları alan / iş katmanına girmeli, yani veri erişim teknolojisi hiç değişmezse, diğer katmanlarım etkilenmez mi?

Şimdiye kadar okuduğum kadarıyla yapım şöyle:

MVC İnternet Uygulaması -> Standart internet projesi - buradaki modeller ViewModels

Etki Alanı / İş katmanı -> denetleyicilerin ilgili görünümlere geçmeden önce veri katmanındaki etki alanı varlıklarını işlemek için kullanabileceği işe özgü sınıflar / modeller

Havuz soyutlaması gerekli mi? -> Özellikle ORM kullanırken bununla ilgili çok fazla tartışma duyuyorum

Veri katmanı -> Varlık sınıfları (Araba, Kamyonet, Motosiklet), DbContext - Beton veri erişim teknolojisi katmanı

Yanıtlar:


26

Sorunuzda çok sayıda hareketli parça var, birçok kavrama dokunuyorsunuz, ancak orta ila büyük ölçekli bir MVC uygulaması hakkında nasıl düşünüleceği konusunda temel tavsiyem:

Sunum <---> İş Mantığı <---> Veri Erişimi

İlk olarak, en iyisi değil "bir MVC uygulaması" olarak uygulamanın düşünüyorum. Sunum bileşeni olarak MVC desenini kullanan bir uygulamadır. Bu şekilde düşünmek, iş mantığı endişelerinizi sunum endişelerinizden ayırmanıza yardımcı olacaktır . Belki de küçük uygulamalar için her şeyi MVC yapısına veritabanına erişmek için yığmak iyidir, ancak orta ila büyük bir uygulama için hızla savunulamaz hale gelir.

MVC (Sunum)

Uygulamanızda, ASP.NET MVC bileşeni, iş verilerini görüntüleme amacıyla (Modeller) dönüştürmek, kullanıcı arabirimini (Görünümler) görüntülemek ve yönlendirme, kimlik doğrulama, yetkilendirme, istek doğrulama, yanıt işleme ve gibi (Kontrolörler). Başka bir şey yapan bir kodunuz varsa , MVC bileşenine ait değildir .

Depo / ORM (Veri Erişimi)

Ayrıca uygulamanızda, veri erişim katmanının kalıcı verilerin alınması ve depolanmasıyla ilgili olması gerekir. Genellikle bu ilişkisel bir veritabanı biçimindedir, ancak verilerin kalıcı olmasının birçok yolu vardır. Kalıcı verileri okumayan veya saklamayan bir kodunuz varsa , veri katmanına ait değildir . Daha önce SO hakkında ORM / Havuz tartışması hakkındaki düşüncelerimi paylaştım , ancak özetlemek gerekirse, bir ORM'yi birkaç nedenden dolayı bir Depo ile aynı şey olarak görmüyorum.

İş mantığı

Artık sunum katmanınız (MVC) ve veri katmanınız (depo veya ORM) var ... Diğer her şey iş mantığı katmanınızdır (BLL). Hangi verilerin alınacağına karar veren veya karmaşık hesaplamalar yapan veya iş kararları veren tüm kodlarınız burada olmalıdır. İş mantığımı genellikle, sunum katmanımın istenen işi yapmak için çağırabileceği 'hizmetler' şeklinde düzenlerim. Tüm alan adı modellerim burada mevcut.

Yaklaşımınız

Bu benim yaklaşımınızın benim için biraz parçalandığı yer. MVC denetleyicinizi depodan veri alacağınız yer olarak tanımlarsınız ve MPGCalculator'a bazı işler yapmak için çağrı yaparsınız, vb. BLL.

Diğer bir deyişle, ben denetleyicisi içine bir depo ve MPGCalculator enjekte o kontrolörünü fazla sorumluluk (zaten tüm başa çıkıyor veriyor olmaz kontrolör yukarıda bahsedilen şeyler). Bunun yerine, tüm bunları BLL'de tutacak bir hizmetim olacak ve sonuçları kontrolöre geri göndereceğim. Daha sonra kontrolör sonuçları doğru modele dönüştürebilir ve doğru görünüme aktarabilir. Denetleyicide herhangi bir iş mantığı yoktur ve denetleyiciye enjekte edilen tek şey uygun BLL hizmetleri olacaktır.

Bu şekilde yapmak, iş mantığınızın (örneğin, bir dizi araç verildiğinde, MPG'yi hesaplayın ve en iyiden en kötüye doğru sıralama ) sunum ve kalıcılık endişelerinden bağımsız olduğu anlamına gelir. Genellikle veri kalıcılığı stratejisini veya sunum stratejisini bilmeyen veya önemsemeyen bir kütüphanede olacaktır.


Merhaba Eric, mükemmel cevap - depolar ile ilgili olarak, somut sınıfların veri erişim katmanında ve iş / hizmet katmanında 'ICarRepository' vb yaşayacağını varsayalım? O zaman denetleyicime gereksinimlere bağlı olarak 1 veya daha fazla depo içerebilecek hizmetler enjekte edebilir miyim?
Michael Harper

@MichaelHarper Evet, kulağa gitmenin mükemmel bir yolu gibi geliyor.
Eric King

1
Kimlik doğrulaması bir denetleyici endişesi olsa da (farklı kullanıcı arayüzleri farklı kimlik doğrulaması yapar) yetkilendirmenin iş mantığı olduğunu ve iş katmanına ait olduğunu söyleyebilirim. Katılıyor musun?
tom

1
@tom Evet, iyi bir noktanız var. Kullanıcının bu rotaya erişimi olduğu gibi basit yetkilendirmeyi düşünüyordum , ancak bundan daha fazlası olabilir. "Çok daha fazlası" kısmı iş katmanına aittir.
Eric King

1
@HunterNelson Bir görünüm modeline eşliyorsanız, eşlemenin sunum katmanında görünümün olduğu yerde gerçekleşmesi gerekir. Başka hiçbir yerde mantıklı olmazdı.
Eric King

0

Her şey yapınız için doğru gibi görünüyor. Emin olmadığım tek şey, MVC'deki modellerin "ViewModels" olduğunu ve denetleyicilerinizin etki alanı katmanıyla konuştuğunu belirtmenizdir. Varsayılan düzeniniz etki alanı katmanına erişmek için denetleyiciyi kullanmak ve daha sonra o görünüm için mantıklı olarak birden çok etki alanı varlıklarından daha görünüme özgü bilgi derlemeleri olarak "ViewModels" kullanmak için bu mantıklı olduğunu düşünüyorum. Yaptığınız şey buysa, muhtemelen iyi olacaksınız.

Eğer varsa, MVC uygulamanızda etki alanı katmanınızı tamamen soyutlamanız gerektiğini düşündüğünüz bir okul var. Şahsen, bunu bir kurumsal uygulamada yapma düşüncesi bana ciddi zihinsel ağrılara neden oluyor.

Veri katmanına erişimi denetlenebilirlik ve esnekliği artırdığı için depo desenini kullanmayı tercih ederim. En sert değişiklikleri yapma eğilimi gösteren iki şey, kullanıcı arayüzü ve veritabanıdır. Doğrudan veritabanından çektiğiniz bilgilerin bir kısmının, veritabanı çağrısı yerine bir hizmet çağrısından alınması gerektiği şekilde değiştirildiğini veya bazı bilgilerin farklı bir .edmx gerektiren farklı bir veritabanına taşındığını düşünün. dosya. Depo deseni bunu desteklemek için soyutlama sağlar.


Cevabınız için teşekkürler William 😊 İş nesnelerimi / mantığımı ve etki alanı varlıklarımı, denetleyicinin kullanıcı eylemlerini ve viewmodels'i model grupları vb. İçerebilecek belirli modelleri görüntülemek için kullandığı 'modeller' olarak değerlendiririm.
Michael Harper
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.