Створення сервісного рівня для моєї програми MVC?


82

З того, що я розумію, MVC відокремлює визначення класу (модель) від презентації (подання) за допомогою "клею", який є контролером. Контролер повинен нести єдину відповідальність і, отже, перевірятися. Моделі ViewModels використовуються для об'єднання даних від декількох об'єктів та для "масажу" даних з контролера для подання.

Здається, діловій логіці насправді не місце ... тому я думаю, що інший рівень послуг буде підходящим. Я просто не впевнений, де розмістити цей шар або як побудувати служби - це повинен бути клас під назвою "послуги", який містить купу функцій? Я трохи новачок у MVC, тому будь-який матеріал для читання, зразки чи загальні підказки щодо нових новинок будуть чудовими.

Відповіді:


126

Я зазвичай використовую сервісний рівень при розробці програми ASP.NET MVC. Подібно до шаблону службового рівня, який Мартін Фаулер обговорює в " Шаблонах архітектури корпоративних додатків" . Це містить вашу бізнес-логіку та робить контролери досить тонкими. В основному контролери використовують сервісний рівень для отримання моделей доменів, які потім трансформуються у моделі представлення. Я також використовую шаблон дизайну одиниці роботи для обробки транзакцій, а шаблон дизайну сховища для інкапсуляції рівня доступу до даних для спрощення модульного тестування та можливості легкої заміни ORM. На цьому малюнку показано типові шари, які я використовую в програмі MVC.

Архітектура MVC

На цій схемі сервісний рівень позначений як "Рівень додатків або доменів", оскільки я вважаю, що люди заплутуються, коли ви використовуєте термін "рівень послуг". Вони схильні думати, що це веб-сервіс. Це насправді збірка, яку можуть використовувати ваші улюблені технології веб-служб, такі як ASP.NET Web API або WCF, а також контролер.

Що стосується конвенцій про іменування, я зазвичай використовую те, що описує домен, а потім службу. Наприклад, якщо у мене є сервісний рівень, який обробляє членство користувачів, тоді я мав би клас під назвою MembershipService, який має всі методи, необхідні контролерам та веб-службам для запиту та маніпулювання доменом членства. Зверніть увагу: у вас може бути кілька доменів в одній програмі, тому ви можете мати кілька рівнів обслуговування. Я маю на увазі те, що вам не потрібно мати одну монолітну службу, яка б опікувалася всією програмою.


7
Чи є хороший приклад, який реалізує цю методологію?
Анімеш

@Animesh, вам просто потрібно скласти приклади в мережі, EF + Code First або POCO шаблон для DAL, T4Scaffolding для створення сховища та UnitOfWork, Служба - це просто координація між DAL та POCO, що інкапсулює бізнес-логіку. Потім контролер ASP.NET MVC АБО WebApi, який викликає лише сервісний рівень і показує результати (ASP.NET MVC) або виставляє його іншому клієнту (ASP.NET WebApi)
riadh gomri

2
Сховище та UoW непотрібні, чи не так? Принаймні у вашому прикладі, коли вам потрібно використовувати лише одну технологію баз даних (а це не DDD). Ось чому EF вже запровадив UoW і шаблони сховищ.
krypru

1
Я не знаю про це, оскільки мені подобаються приклад та малюнок, але багато навчальних посібників в Інтернеті використовують шаблон сховища без потреби. Вони абстрагуються, тому що можуть абстрагуватися без користі, просто щоб вони могли використовувати Інтерфейс.
johnny

Чудово !!! Дякую @kevin Junghans, Ваша відповідь справді допомогла мені створити складний веб-додаток. Одне коротке запитання: Розробляючи веб-програми на базі мікросервісів, чи потрібно нам впроваджувати класи обслуговування або просто MVC-класи виконують цю роботу.
codemilan

28

Моя порада - створити окремі класи під назвою «послуги». Помістіть їх до проекту бібліотеки різних класів (або простору імен) та зробіть незалежними від інфраструктури MVC. Я рекомендую використовувати також якусь ін'єкцію залежностей (найкраща - це ін'єкція конструктора). Тоді ваші класи обслуговування можуть виглядати так:

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

     public MyService(IFirstDependency firstService, ISecondDependency secondService)
     {
     }

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

Потім ви користуєтесь цією послугою від своїх контролерів. Шукайте тут повний приклад.

Відповідно до сховищ - моя порада - не використовувати їх, якщо ви збираєтеся використовувати якийсь сучасний ORM (NHibernate, EntityFramework), оскільки ваша бізнес-логіка буде інкапсульована на рівні обслуговування, а ваша база даних вже буде інкапсульована в структуру ORM.


4
Я думаю, що проблема з пропуском розділу сховища та прямим переходом до ORM полягає в тому, що ваші класи послуг безпосередньо отримають контекст ORM, що означає, що всі ці класи у вашій службі матимуть доступ до всіх таблиць, які ви втягли в контекст, замість кожної служби клас, який працює лише з потрібними таблицями. Ви можете уникнути цього, передавши DbSet's у ctor кожного класу та вирішивши це за допомогою DI, але у вас можуть виникнути проблеми з цим?
user441521


10

Цитата з "Бізнес-логіка повинна бути в службі, а не в моделі"? :

В архітектурі MVP / MVC / MVVM / MV * служби взагалі не існують. Або якщо вони це роблять, цей термін використовується для позначення будь-якого загального об'єкта, який може бути введений в контролер або модель перегляду. Бізнес-логіка - у вашій моделі. Якщо ви хочете створити "сервісні об'єкти" для організації складних операцій, це розглядається як деталь реалізації. Багато людей, на жаль, впроваджують MVC, як це, але це вважається анти-шаблоном (Anemic Domain Model), оскільки сама модель нічого не робить, це лише купа властивостей для інтерфейсу користувача.

Деякі люди помилково думають, що використання методу 100-рядкового контролера і введення його у службу якимось чином покращує архітектуру. Це справді не так; все, що він робить, - це додати ще один, можливо, непотрібний шар непрямості. Практично кажучи, контролер все ще виконує роботу, він просто робить це через погано названий об’єкт «помічник». Я настійно рекомендую презентацію " Моделі злих доменів" Джиммі Богарда для наочного прикладу того, як перетворити анемічну модель домену на корисну. Він передбачає ретельне вивчення моделей, які ви виставляєте, та операцій, які насправді є дійсними в бізнес-контексті.


Це найкраща відповідь. Обраний каже, що бізнес-логіку слід використовувати на послугах, які будуть використовуватися в контролері, але бізнес-логіка повинна бути на моделі.
Матеус Феліпе

3

Здається, ви хотіли б щось подібне до шаблону сховища. Про це ви можете прочитати тут:

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net- mvc-додаток

Ця відповідь тут також може допомогти:

Найкращий шаблон сховища для ASP.NET MVC


4
Це набагато більше, ніж просто шаблон сховища. Послуги перебувають в доступі до даними теж , але не тільки имхо.
бой
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.