programing

서비스 계층이 MVC 애플리케이션에 대한 뷰 모델을 반환해야합니까?

nasanasas 2020. 12. 1. 08:08
반응형

서비스 계층이 MVC 애플리케이션에 대한 뷰 모델을 반환해야합니까?


ASP.NET MVC 프로젝트가 있고 asp.net 사이트의 연락처 관리자 자습서에서와 같이 서비스 계층을 사용하고 있다고 가정합니다. http://www.asp.net/mvc/tutorials/iteration-4-make- 애플리케이션 느슨하게 결합 된 cs

뷰에 대한 뷰 모델이있는 경우 서비스 계층이 각 뷰 모델을 제공하기에 적합한 위치입니까? 예를 들어 서비스 계층 코드 샘플에는

    public IEnumerable<Contact> ListContacts()
    {
        return _repository.ListContacts();
    }

대신 IEnumerable을 원하면 서비스 계층에 있어야합니까, 아니면 "올바른"장소가있는 다른 곳에 있습니까?

아마도 더 적절하게는 ContactController와 관련된 각 뷰에 대해 별도의 뷰 모델이있는 경우 ContactManagerService에 각 뷰 모델을 반환하는 별도의 메서드가 있어야합니까? 서비스 계층이 적절한 위치가 아닌 경우 컨트롤러에서 사용하기 위해 viewmodel 객체를 어디에서 초기화해야합니까?


일반적으로 아닙니다.

보기 모델은보기에서 정보를 제공하기위한 것이며 일반 도메인이 아닌 애플리케이션에 고유해야합니다. 컨트롤러는 리포지토리, 서비스 (여기서는 서비스 정의에 대한 몇 가지 가정을하고 있음) 등과의 상호 작용을 조율하고 뷰 모델의 빌드 및 유효성 검사를 처리해야하며 렌더링 할 뷰를 결정하는 논리도 포함해야합니다.

뷰 모델을 "서비스"계층으로 유출함으로써 계층을 모호하게 만들고 이제는 도메인 수준의 책임에 초점을 맞춰야하는 것과 혼합 된 가능한 애플리케이션 및 프레젠테이션을 갖게됩니다.


아니요, 그렇게 생각하지 않습니다. 서비스는 결과를 렌더링하는 뷰가 아닌 문제 도메인에만 관심을 가져야합니다. 반환 값은 뷰가 아닌 도메인 개체로 표현되어야합니다.


전통적인 접근 방식 또는 이론적 측면에 따라 ViewModel은 사용자 인터페이스 계층의 일부 여야합니다. 적어도 이름은 그렇게 말합니다.

그러나 Entity Framework, MVC, Repository 등으로 직접 구현하면 다른 것을 깨닫게됩니다.

누군가는 Entity / DB 모델을 ViewModels (마지막에 언급 된 DTO)로 매핑해야합니다. [A] UI 레이어 (컨트롤러에 의해) 또는 [B] 서비스 레이어에서이 작업을 수행해야합니까?

옵션 B를 선택합니다. 여러 엔터티 모델이 결합되어 ViewModel을 형성한다는 단순한 사실 때문에 옵션 A는 아니오입니다. 불필요한 데이터를 UI 레이어에 전달하지 않을 수 있지만, 옵션 B에서는 서비스가 데이터를 가지고 플레이 할 수 있으며 매핑 (ViewModel에) 후 UI 레이어에 필요한 / 최소값 만 전달할 수 있습니다.

다시 한 번 옵션 A로 가서 ViewModel을 UI 계층 (및 서비스 계층의 엔티티 모델)에 넣습니다.

서비스 계층이 ViewModel에 매핑해야하는 경우 서비스 계층은 UI 계층의 ViewModel에 액세스해야합니다. 어떤 라이브러리 / 프로젝트? Viewmodel은 UI 레이어의 별도 프로젝트에 있어야하며이 프로젝트는 서비스 레이어에서 참조해야합니다. ViewModel이 별도의 프로젝트에 없으면 순환 참조가 있으므로 이동하지 마십시오. 서비스 계층이 UI 계층에 액세스하는 것이 어색해 보이지만 여전히 대처할 수 있습니다.

하지만이 서비스를 사용하는 다른 UI 앱이 있다면 어떨까요? 모바일 앱이 있다면? ViewModel은 얼마나 다를 수 있습니까? 서비스가 동일한 뷰 모델 프로젝트에 액세스해야합니까? 모든 UI 프로젝트가 동일한 ViewModel 프로젝트에 액세스합니까 아니면 자체 프로젝트가 있습니까?

이러한 고려 사항 후에 내 대답은 Viewmodel 프로젝트를 서비스 계층에 배치하는 것입니다. 모든 UI 계층은 어쨌든 서비스 계층에 액세스해야합니다! 그리고 그들이 모두 사용할 수있는 유사한 ViewModel이 많이있을 수 있습니다 (따라서 서비스 레이어의 매핑이 더 쉬워집니다). 요즘에는 linq를 통해 매핑이 이루어지며 이는 또 다른 장점입니다.

마지막으로 DTO에 대한 논의가 있습니다. 또한 ViewModels의 데이터 주석에 대해서도 설명합니다. 데이터 주석이있는 ViewModel (Microsoft.Web.Mvc.DataAnnotations.dll)은 UI 계층에 상주하는 대신 서비스 계층에 상주 할 수 없습니다 (그러나 ComponentModel.DataAnnotations.dll은 서비스 계층에 상주 할 수 있음). 모든 프로젝트가 하나의 솔루션 (.sln)에있는 경우 어떤 레이어를 배치하든 상관 없습니다. 엔터프라이즈 응용 프로그램에서 각 계층에는 자체 솔루션이 있습니다.

따라서 DTO는 실제로 ViewModel입니다. 대부분 둘 사이에 일대일 매핑이 있기 때문입니다 (예 : AutoMapper). 다시 DTO는 UI (또는 여러 애플리케이션)에 필요한 로직을 가지고 있으며 서비스 계층에 상주합니다. 그리고 UI 레이어 ViewModel (Microsoft.Web.Mvc.DataAnnotations.dll을 사용하는 경우)은 DTO에서 데이터를 복사하고 일부 '동작'/ 속성을 추가하는 것입니다.

[이제이 토론은 흥미로운 차례가 될 것입니다 ... : I]

그리고 데이터 주석 속성이 UI만을위한 것이라고 생각하지 마십시오. System.ComponentModel.DataAnnotations.dll을 사용하여 유효성 검사를 제한하면 프런트 엔드 및 백엔드 유효성 검사에도 동일한 ViewModel을 사용할 수 있습니다 (따라서 UI-residing-ViewModel-copy-of-DTO 제거). 또한 속성은 엔티티 모델에서도 사용할 수 있습니다. 예 : .tt를 사용하여 Entity Framework 데이터 모델을 유효성 검사 특성으로 자동 생성하여 백 엔드로 보내기 전에 max-length와 같은 일부 DB 유효성 검사를 수행 할 수 있습니다. 또 다른 장점은 DB에서 백엔드 유효성 검사가 변경되면 .tt (DB 세부 정보를 읽고 엔티티 클래스에 대한 속성을 생성)가 자동으로 선택한다는 것입니다. 이로 인해 UI 유효성 검사 단위 테스트도 실패 할 수 있으며 이는 큰 장점입니다 (따라서 실수로 잊어 버리거나 실패하는 대신 모든 UI / 소비자에게이를 수정할 수 있음). 예, 토론은 좋은 프레임 워크 디자인으로 이동하고 있습니다. 보시다시피 계층 별 유효성 검사, 단위 테스트 전략, 캐싱 전략 등 모두 관련되어 있습니다.

질문과 직접 ​​관련이 없지만. 여기에 언급 된 'ViewModel Façade'는 반드시 시청해야하는 채널 9 링크 도 살펴볼 가치가 있습니다. 비디오에서 정확히 11 분 49 초에 시작됩니다. 위에 주어진 현재 질문이 분류되면 다음 단계 / 생각이 될 것이기 때문에 : 'ViewModels를 구성하는 방법?'

또한 예에서 "_repository.ListContacts ()"는 저장소에서 ViewModel을 반환합니다. 이것은 성숙한 방법이 아닙니다. 리포지토리는 엔티티 모델 또는 DB 모델을 제공해야합니다. 이것은 뷰 모델로 변환되고 서비스 계층에서 반환되는 뷰 모델입니다.


나는 그것이 당신이 "서비스"라고 생각하는 것에 달려 있다고 생각합니다. 저는 단일 클래스의 맥락에서 서비스 라는 용어를 정말 좋아 한 적이 없습니다 . 엄청나게 모호하고 수업의 실제 목적에 대해 많이 알려주지 않습니다.

"서비스 계층"이 웹 서비스와 같은 물리적 계층이면 절대 그렇지 않습니다. SOA 컨텍스트의 서비스는 프레젠테이션 로직이 아닌 데이터가 아닌 도메인 / 비즈니스 운영을 노출해야합니다. 그러나 서비스 가 추가 수준의 캡슐화를위한 추상적 인 개념으로 사용되는 경우에는 원하는 방식으로 사용하는 데 아무런 문제가 없습니다.

개념을 혼합하지 마십시오. 서비스가 뷰 모델을 다루는 경우 프레젠테이션 서비스 여야하며 실제 모델 위에 계층화되어야 하며 데이터베이스 나 비즈니스 로직에 직접 닿지 않아야합니다.


이것은 내가 일하는 위치에 따라 약간의 "다름"이 발생했습니다. 일반적으로 컨트롤러가 일부 서비스를 소비하고 있습니다. 그런 다음 반환 된 DTO를 'ViewModel'로 결합하여 JSON 결과를 통해 클라이언트에 전달합니다. , 또는 Razor 템플릿에 바인딩됩니다.

Thing is, about 80% of the time - the mapping of DTO to ViewModel has been 1-1. We are starting to move towards 'Where needed, just consume the DTO directly, but when the DTO and what we need in our client/view don't match up - then we create a ViewModel and do the mapping between objects as needed'.

Although I'm still not convinced that this is the best or right solution - as it ends up leading to some heated discussions of 'are we just adding X to the DTO to meet the needs of the view?'

참고URL : https://stackoverflow.com/questions/3002168/should-a-service-layer-return-view-models-for-an-mvc-application

반응형