내 MVC 애플리케이션에 대한 서비스 계층을 생성합니까?


82

내가 이해하는 바에 따르면 MVC는 컨트롤러 인 "접착제"를 통해 프레젠테이션 (보기)에서 클래스 정의 (모델)를 분리합니다. 컨트롤러는 단일 책임을 가져야하므로 테스트 할 수 있어야합니다. ViewModel은 여러 엔터티의 데이터를 모으고 뷰에 대한 컨트롤러의 데이터를 "마사지"하는 데 사용됩니다.

비즈니스 로직에는 실제로 자리가없는 것 같습니다. 그래서 서비스를위한 다른 계층이 적합 할 것이라고 생각합니다. 이 레이어를 어디에 배치해야하는지 또는 서비스를 구축하는 방법을 잘 모르겠습니다. 여러 기능을 포함하는 "서비스"라는 클래스 여야합니까? 나는 MVC를 처음 접했기 때문에 어떤 독서 자료, 샘플 또는 일반적인 신참 팁이 굉장 할 것입니다.

답변:


126

ASP.NET MVC 응용 프로그램을 개발할 때 일반적으로 서비스 계층을 사용합니다. Martin Fowler가 Patterns of Enterprise Application Architecture 에서 논의 하는 서비스 계층 패턴 과 유사합니다 . 비즈니스 로직을 캡슐화하고 컨트롤러를 매우 얇게 만듭니다. 기본적으로 컨트롤러는 서비스 계층을 사용하여 도메인 모델을 가져온 다음 뷰 모델로 변환합니다. 또한 작업 단위 디자인 패턴 을 사용하여 트랜잭션을 처리하고 저장소 디자인 패턴 을 사용하여 데이터 액세스 계층을 캡슐화하여 더 쉽게 단위 테스트를 수행하고 ORM을 쉽게 교체 할 수 있습니다. 이 그림은 MVC 애플리케이션에서 사용하는 일반적인 레이어를 보여줍니다.

MVC 아키텍처

서비스 계층은 "서비스 계층"이라는 용어를 사용할 때 사람들이 혼란스러워하기 때문에이 다이어그램에서 "응용 프로그램 또는 도메인 계층"으로 레이블이 지정됩니다. 그들은 이것이 웹 서비스라고 생각하는 경향이 있습니다. 실제로 ASP.NET Web API 또는 WCF와 같은 좋아하는 웹 서비스 기술과 컨트롤러에서 사용할 수있는 어셈블리입니다.

명명 규칙에 관해서는 일반적으로 서비스 다음에 도메인을 설명하는 것을 사용합니다. 예를 들어, 사용자 멤버십을 처리하는 서비스 계층이있는 경우 멤버십 도메인을 쿼리하고 조작하기 위해 컨트롤러 및 웹 서비스에 필요한 모든 메서드를 포함하는 MembershipService라는 클래스가 있습니다. 동일한 애플리케이션에 여러 도메인이있을 수 있으므로 여러 서비스 계층을 가질 수 있습니다. 내 요점은 전체 애플리케이션을 처리하는 하나의 모 놀리 식 서비스를 가질 필요가 없다는 것입니다.


7
이 방법론을 구현하는 좋은 예가 있습니까?
Animesh

@Animesh는 net, EF + Code First 또는 DAL 용 POCO 템플릿, Repository 및 UnitOfWork 생성을위한 T4Scaffolding, Service는 비즈니스 로직을 캡슐화하는 DAL 및 POCO 간의 조정일뿐입니다. 그런 다음 서비스 계층 만 호출하고 결과 (ASP.NET MVC)를 표시하거나 다른 클라이언트 (ASP.NET WebApi)에 노출하는 ASP.NET MVC 컨트롤러 또는 WebApi
riadh gomri 2013

2
저장소와 UoW는 불필요하지 않습니까? 최소한 하나의 데이터베이스 기술을 사용해야 할 때 (DDD가 아님) 적어도 귀하의 예에서는. 이것이 EF가 이미 UoW 및 저장소 패턴 자체를 구현 한 이유입니다.
krypru

1
예제와 그래픽이 마음에 들어 여기에 대해서는 잘 모르겠지만 온라인 자습서에서는 리포지토리 패턴을 불필요하게 사용합니다. 그들은 아무런 이점없이 추상화 할 수 있기 때문에 추상화합니다. 단지 인터페이스를 사용할 수 있습니다.
조니

대박 !!! @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         
     }
 }

그런 다음 컨트롤러에서 이러한 서비스를 사용합니다. 봐 여기에 완벽한 예를 들어.

Repositories에 따르면-비즈니스 로직이 서비스 계층에 캡슐화되고 데이터베이스가 이미 ORM 프레임 워크로 캡슐화되므로 최신 ORM (NHibernate, EntityFramework)을 사용하려는 경우에는 사용하지 않는 것이 좋습니다.


4
저장소 섹션을 건너 뛰고 ORM으로 바로 이동하는 문제는 서비스 클래스가 ORM 컨텍스트를 직접 가져 오므로 서비스의 모든 클래스가 각 서비스 대신 컨텍스트로 가져온 모든 테이블에 액세스 할 수 있다는 것입니다. 필요한 테이블로만 작업하는 클래스. DbSet을 각 클래스의 ctor에 전달하고 DI로 해결하면 이것을 피할 수 있지만 문제가 발생할 수 있습니까?
user441521


10

"비즈니스 로직은 모델이 아닌 서비스에 있어야합니다" 에서 인용 합니까? :

MVP / MVC / MVVM / MV * 아키텍처에서는 서비스가 전혀 존재하지 않습니다. 또는 만약 그렇다면,이 용어는 컨트롤러 나 뷰 모델에 삽입 될 수있는 일반적인 객체를 가리키는 데 사용됩니다. 비즈니스 로직은 모델에 있습니다. 복잡한 작업을 오케스트레이션하기 위해 "서비스 개체"를 생성하려는 경우 구현 세부 사항으로 간주됩니다. 슬프게도 많은 사람들이 MVC를 이와 같이 구현하지만 모델 자체가 아무 작업도 수행하지 않기 때문에 안티 패턴 (Anemic Domain Model)으로 간주됩니다. UI에 대한 속성의 집합 일뿐입니다.

어떤 사람들은 100 라인 컨트롤러 방법을 취하고 모든 것을 서비스에 밀어 넣으면 더 나은 아키텍처가된다고 잘못 생각합니다. 정말 그렇지 않습니다. 그것은 아마도 불필요한 간접 계층을 추가하는 것뿐입니다. 실제로 컨트롤러는 여전히 작업을 수행하고 있으며 이름이 잘못된 "도우미"개체를 통해 수행합니다. 빈혈 도메인 모델을 유용한 모델로 바꾸는 방법에 대한 명확한 예를 보려면 Jimmy Bogard의 Wicked Domain Models 프레젠테이션을 적극 권장 합니다. 노출하는 모델과 비즈니스 컨텍스트에서 실제로 유효한 작업을주의 깊게 조사해야합니다.


이것이 최고의 답변입니다. 선택된 것은 컨트롤러에서 사용할 서비스에 비즈니스 로직을 배치하라고 말하지만 비즈니스 로직은 모델에 있어야합니다.
Mateus Felipe

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
저장소 패턴 그 이상입니다. 서비스는 데이터 액세스에 대한 있습니다 너무 아니지만 독점적 이럴.
boj
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.