MVC uygulamam için bir Hizmet Katmanı mı oluşturuyorsunuz?


82

Anladığım kadarıyla MVC, sınıf tanımlarını (model) sunumdan (görünüm) denetleyici olan "yapıştırıcı" aracılığıyla ayırıyor. Kontrolörün tek bir sorumluluğu olmalı ve bu nedenle test edilebilir olmalıdır. ViewModels, birden çok varlıktan gelen verileri bir araya getirmek ve görünüm için denetleyicideki verileri "masaj yapmak" için kullanılır.

İş mantığının gerçekten bir yeri yok gibi görünüyor ... bu yüzden hizmetler için başka bir katmanın uygun olacağını düşünüyorum. Bu katmanı nereye yerleştireceğimi ya da hizmetleri nasıl oluşturacağımı bilmiyorum - bu, bir grup işlev içeren "hizmetler" adlı bir sınıf mı olmalı? MVC'de biraz yeniyim, bu yüzden herhangi bir okuma materyali, örnek veya genel olarak yeni gelen ipuçları harika olurdu.

Yanıtlar:


126

ASP.NET MVC uygulamasını geliştirirken genellikle bir Hizmet Katmanı kullanıyorum. Martin Fowler'ın Patterns of Enterprise Application Architecture'da tartıştığı Hizmet Katmanı Modeline benzer . İş mantığınızı kapsar ve denetleyicileri oldukça ince hale getirir. Temel olarak denetleyiciler, daha sonra görünüm modellerine dönüştürülen etki alanı modellerini almak için hizmet katmanını kullanır. Ben de kullanmak Birimi Çalışma Tasarım Desen kolu işlemlerine ve Depo Tasarımı Desen kolay ünite testleri için veri erişim katmanı saklanması ve ORM dışarıda kolayca takas edememek. Bu şekil, bir MVC uygulamasında kullandığım tipik katmanları göstermektedir.

MVC Mimarisi

Hizmet katmanı bu şemada "Uygulama veya Etki Alanı Katmanı" olarak etiketlenmiştir çünkü "Hizmet Katmanı" terimini kullandığınızda insanların kafasının karıştığını görüyorum. Bunun bir web hizmeti olduğunu düşünme eğilimindeler. Aslında ASP.NET Web API veya WCF gibi favori web hizmeti teknolojiniz ve bir denetleyici tarafından kullanılabilen bir derlemedir.

Adlandırma kurallarına gelince, genellikle hizmetin izlediği etki alanını tanımlayan bir şey kullanırım. Örneğin, kullanıcı üyeliğini işleyen bir hizmet katmanım varsa, denetleyiciler ve web hizmetleri tarafından üyelik etki alanını sorgulamak ve işlemek için gereken tüm yöntemlere sahip olan MembershipService adlı bir sınıfım olur. Aynı uygulamada birden fazla etki alanınız olabileceğini ve böylece birden çok hizmet katmanına sahip olabileceğinizi unutmayın. Demek istediğim, tüm uygulama ile ilgilenen tek bir monolitik hizmete sahip olmanız gerekmiyor.


7
Bu metodolojiyi uygulayan iyi bir örnek var mı?
Animesh

@Animesh, sadece ağdaki örneklerle, DAL için EF + Code First veya POCO şablonuyla, Depo oluşturmak için T4Scaffolding ve UnitOfWork ile oluşturmalısınız, Servis sadece DAL ve POCO'nun iş mantığını kapsayan koordinasyonudur. Ardından, yalnızca hizmet katmanını çağıran ve sonuçları (ASP.NET MVC) gösteren veya başka bir istemciye (ASP.NET WebApi) gösteren ASP.NET MVC Denetleyicisi VEYA WebApi
riadh gomri

2
Depo ve UoW gereksiz, değil mi? En azından örneğinizde, yalnızca bir veritabanı teknolojisini kullanmanız gerektiğinde (ve bu DDD değil). Bu nedenle EF zaten UoW ve depo kalıplarını kendisi uygulamıştır.
krypru

1
Örnek ve grafiği sevdiğim için burayı bilmiyorum, ancak çevrimiçi olarak birçok eğitici Depo Modelini gereksiz yere kullanıyor. Soyutlar çünkü hiçbir faydası olmadan soyutlayabilirler, sırf Arayüz kullanabilmek için.
johnny

Harika !!! Teşekkür ederim @kevin Junghans, Cevabınız gerçekten karmaşık bir web uygulaması tasarlamama yardımcı oldu. Kısa bir soru, Mikro servis tabanlı web uygulamaları geliştirirken, Servis sınıfları uygulamalı mıyız yoksa sadece MVC sınıfları işi yapar.
codemilan

28

Benim tavsiyem, "hizmetler" adı verilen ayrı bir sınıf oluşturmaktır. Bunları farklı sınıf kitaplığı (veya ad alanı) projesine yerleştirin ve MVC çerçeve altyapısında bağımsız hale getirin. Ayrıca bir çeşit bağımlılık enjeksiyonu kullanmanızı tavsiye ederim (en iyisi yapıcı enjeksiyonu). O zaman hizmet sınıflarınız şöyle görünebilir:

 public class MyService : IMyService
 {
     IFirstDependency _firstService;
     ISecondDependency _secondService;

     public MyService(IFirstDependency firstService, ISecondDependency secondService)
     {
     }

     public Result DoStuf(InputDTO)
     {
         // some important logic         
     }
 }

Daha sonra bu hizmetleri kontrol cihazlarınızdan alırsınız. Tam örnek için buraya bakın .

Depolara göre - benim tavsiyem, bazı modern ORM (NHibernate, EntityFramework) kullanacaksanız bunları kullanmamanızdır, çünkü iş mantığınız Hizmet Katmanında kapsüllenecek ve veritabanınız zaten ORM çerçevesi ile kapsüllenmiş olacaktır.


4
Bence depo bölümünü atlamak ve ORM'ye gitmekle ilgili sorun, hizmet sınıflarınızın doğrudan ORM bağlamını almasıdır; bu, hizmetinizdeki tüm bu sınıfların her hizmet yerine içeriğe çektiğiniz tüm tablolara erişebileceği anlamına gelir. Sadece ihtiyaç duyduğu tablolarla çalışan sınıf. Bunu, DbSet'leri her sınıfın ctor'una geçirip bunu DI ile çözerek önleyebilirdiniz, ancak bununla ilgili sorunlarla karşılaşabilirsiniz?
user441521


10

"İş mantığı bir modelde değil, bir hizmette olmalıdır" dan alıntı yapmak ? :

Bir MVP / MVC / MVVM / MV * mimarisinde hizmetler hiç mevcut değildir. Veya yaparlarsa, terim bir denetleyiciye veya görünüm modeline enjekte edilebilen herhangi bir genel nesneyi ifade etmek için kullanılır. İş mantığı sizin modelinizdedir. Karmaşık işlemleri düzenlemek için "hizmet nesneleri" oluşturmak istiyorsanız, bu bir uygulama ayrıntısı olarak görülür. Maalesef pek çok insan MVC'yi bu şekilde uyguluyor, ancak modelin kendisi hiçbir şey yapmadığı için bu bir anti-model (Anemic Domain Model) olarak kabul ediliyor, sadece UI için bir sürü özellik.

Bazı insanlar yanlışlıkla 100 hatlı bir kontrolör yöntemini alıp hepsini bir hizmete sokmanın bir şekilde daha iyi bir mimari yaptığını düşünüyor. Gerçekten yok; tüm yaptığı muhtemelen gereksiz başka bir yönlendirme katmanı eklemektir. Pratik olarak konuşursak, denetleyici hala işi yapıyor, bunu sadece kötü adlandırılmış "yardımcı" bir nesne aracılığıyla yapıyor. Anemik bir alan modelinin nasıl yararlı bir modele dönüştürüleceğine dair net bir örnek için Jimmy Bogard'ın Wicked Domain Models sunumunu şiddetle tavsiye ederim . Gösterdiğiniz modellerin ve hangi işlemlerin bir iş bağlamında gerçekten geçerli olduğunun dikkatli bir şekilde incelenmesini içerir.


Bu en iyi cevap. Seçilen kişi, denetleyicide kullanılacak hizmetlere iş mantığı koymasını söylüyor, ancak iş mantığı modelde olmalı.
Mateus Felipe

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.