14

현재 응용 프로그램에서 작업 단위 (UOW) 패턴과 일반 저장소를 사용하면 모든 컨트롤러에 모든 비즈니스 논리가 포함됩니다. 나는 직선 모델 대신에 ViewModels를 사용하기 위해 모든 것을 처리하는 중입니다.MVC 3 - 컨트롤러 및 ViewModels - 대부분의 비즈니스 로직을 포함해야합니까?

이것은 좋은 생각이지만 지금은 컨트롤러에서 비즈니스 로직을 크게 구분할 수있는 질문이 왔습니다. 대부분의 비즈니스 로직을 포함해야하는 컨트롤러와 ViewModel의 경우?

나는 모든 비즈니스 로직을 실질적으로 포함하도록 내 ViewModel을 얻는 몇 가지 방법을 시도했다. 그러나 작업 단위 (Unit of Work)를 사용하는 ViewModel의 생성자에 인수가 있어야합니다. 이것은 좋은 생각입니까?

내 코드 냄새가 나에게 알려줍니다. 그러나 ViewModel이 필요없는 작업을 수행하는 컨트롤러와 어떻게 일관성이 있는지 조금만 걱정됩니다. 간단히 말해, Model/ViewModel을 뷰에 전달할 필요가없는 액션. 이 경우는 다른 작업으로 리디렉션되는 작업에서 발생합니다. 즉, 내 비즈니스 로직은 그 행동에 머물러있을 수도 있고 비즈니스 로직을 기능으로 분리 할 수도 있습니다.

가장 좋은 방법은 무엇입니까?

답변

7

대부분의 비즈니스 로직을 포함해야하는 컨트롤러 및 ViewModels의 경우?

해당 사항 없음.

필자는 실제적으로 모든 비즈니스 로직을 포함하도록 ViewModel을 얻는 몇 가지 방법을 시도했습니다. 그러나 작업 단위 (Unit of Work)를 사용하는 ViewModel의 생성자에 인수가 있어야합니다. 이것은 좋은 생각입니까?

imho 아주 좋은 생각입니다. 우선 여러분은 여러 가지 강건한 원칙을 깨고 있습니다. 모든 코드를 뷰 모델에 포함 시키면 테스트하기가 어렵습니다. 다른 뷰에서 비즈니스 로직 중 일부를 사용하려면 어떻게해야할까요? 그 코드를 복제합니까?

가장 좋은 방법은 무엇입니까?

먼저 MVC 패턴으로 돌아가 보겠습니다. 그것은 꽤 넓은 정의이지만, 당신이 어디에 배치해야하는지에 대한 느낌을 주어야한다는 것을 안다.

  • MVC의 "모델"은 실제로 데이터를 함께 가져 오는 데 사용되는 모든 것입니다. 웹 서비스, 비즈니스 계층, 리포지토리 등이 될 수 있습니다.

  • 뷰는 HTML을 생성하는 모든 코드입니다 (웹에 대한 이야기이므로).

  • 컨트롤러는 모델과 뷰 사이에 접착제로 간주되어야합니다. 따라서 모델로부터 정보를 가져 와서 뷰에서 사용할 수있는 것으로 변환해야합니다.

해당 구조의 문제점은 패턴의 다른 부분으로 특정 정보를 "누설"하는 것이 매우 쉽다는 것입니다. 따라서 Microsoft는 MVC 구현에 ViewModel을 도입했습니다.

이렇게하면 뷰에서 모든 렌더링 논리를 제거하고이를 ViewModel에 넣을 수 있습니다. 대신보기에이 일의 :

<span>@(model.Age == 0 ? "n/a" : model.Age)</span> 

대신 뷰 모델 안에 그 코드를 넣어 간단하게 @model.Age를 호출합니다. 이 방법으로 뷰 모델을 사용하는 모든 뷰에서 해당 코드를 복제 할 필요가 없습니다.

ViewModel에 대한 질문에 대한 대답은 "모델"의 정보를 올바르게 렌더링하는 데 사용되는 논리 만 포함해야한다는 것입니다.

컨트롤러에 관해서는 비즈니스 로직도 넣지 않을 것입니다. 우선, 그것은 당신의 논리를 테스트하는 것을 매우 어렵게 만듭니다. 그런 다음 책임을 추가합니다 (SRP 위반). 컨트롤러에서 유효한 유일한 논리는 ViewModel에서 정보를 가져 와서 "모델"에서 사용할 수있는 것으로 변환하는 것입니다. 그 반대의 경우도 마찬가지입니다.

귀하의 질문에 대한 답변입니다.

나는 별도의 프로젝트를 만들고 그것에 클래스를 추가 할

업데이트. 그런 다음 웹 프로젝트에서 참조를 추가하고 컨트롤러에서 해당 클래스를 호출하십시오.

컨트롤 컨테이너의 반전을 사용하여 나를 위해 자동으로 생성 된 종속성을 얻을 수도 있습니다.

Autofac은 모두 서비스를 검색하고 (제로 구성) 자신을 MVC에 삽입 할 수 있습니다.

는 분리 된 인터페이스 패턴은 다음과 같은 프로젝트를 만들 따르십시오 :

  • YourProject.BusinessLayer <를 - 여기 클래스 추가
  • YourProject.BusinessLayer.Specification < - 귀하의 비즈니스 계층을 정의하는 당신에게 인터페이스 추가 이리.
  • YourProject.Mvc < - MVC 프로젝트.

은 "사양"프로젝트는 (몇 클래스와 반드시 전체 비즈니스 계층 수 있습니다) 쉽게 물건을 테스트하고 쉽게 구현을 전환 할 수 있도록하는 데 사용할 수 있습니다. "분리 된 인터페이스 패턴"을 읽어보십시오. 컨트롤러가 UoW를 호출하여 뷰 모델 구성에 필요한 데이터를 얻습니다.

+1

좋은 답변입니다. 내 비즈니스 논리가 어디로 갈 것인지 물어보고 싶습니다. – TIHan

+0

내 업데이트 읽기. – jgauffin

+0

감사합니다. 나는 이것을 조사하기 시작할 것이다. – TIHan

10

필자의 접근 방식이 최선의 방법이라고 말할 수는 없지만 비즈니스 로직을 별도의 "서비스"계층에 넣는 것을 선호합니다.

ViewModel을 사용하여 특정보기에 필요한 속성 만 저장하는 경향이 있습니다. ViewModel에 메소드가있는 경우 해당 뷰와 관련된 콜렉션을 검색하는 것일 수 있습니다.

컨트롤러를 유효성 검사 및 리디렉션 /보기 표시를 가능한 한 많이 제한하여 컨트롤러를 경량으로 유지합니다.

그렇다면 복잡한 논리가있는 경우 컨트롤러 동작을 통해 해당 논리를 처리하기 위해 별도의 서비스를 호출해야합니다. 이렇게하면 로직을 고립시켜 검사하기가 더 이상 필요 없기 때문에 컨트롤러를 만들거나 ViewModel을 테스트 할 필요가 없기 때문에 테스트가 더 쉽습니다. ViewModel을 선택하는 것보다 서비스를 재사용하는 것이 더 쉽습니다.

이 정보가 도움이되기를 바랍니다. 행운을 빕니다.

+0

+1 - 이것은 합리적인 접근 방식처럼 보인다; 그러나 제 질문은 아직 답변되지 않았습니다. 저는 ViewModel이 무엇인지 알고 있습니다. 저는 ViewModel이 가능한 한 많은 비즈니스 로직을 포함해야하는지 알아 내려고하고 있습니다. – TIHan

+2

@ TIHan, 그는 ViewModel이 데이터 만 포함한다고 말했다. 서비스가 처리합니다. 컨트롤러가 트래픽 제어를 수행합니다. –

+0

ViewModel은보기의 모든 최종 데이터가 포함 된 [poco] (http://en.wikipedia.org/wiki/Plain_Old_CLR_Object)이어야합니다. 데이터를 가져 와서 처리하고 형식을 지정하는 등의 작업을 수행 할 수 있습니다. 서비스 계층까지 처리 할 수 ​​있습니다. –

3

MVVM (Model-View-View Model)은 사용자 인터페이스를 작성하기위한 디자인 패턴입니다. 보기 모델은 UI에 대한 데이터 및 작업의 순수한 코드 표현입니다. 따라서 해당 UI와 관련된 로직을 포함해야합니다. 예를 들어

는 :

당신이 목록 편집기를 구현하는 경우

,보기 모델 항목의 목록을 들고 객체가 될 것이고, 방법을 노출시키는 항목을 추가 및 제거 할 수 있습니다. 위키

:

의 ViewModel : 뷰 모델이 또한 보기와 모델 사이에 데이터 바인딩에서 제공하는보기의 추상화 의미 "보기의 모델"입니다. 이 Model 정보를 View 정보 으로 변경하고 뷰에서 모델로 명령을 전달하는 데이터 형식의 바인더/변환기 역할을하는 컨트롤러 (MVC 패턴)의 특수한 측면으로 볼 수 있습니다. ViewModel 은 공용 속성, 명령 및 추상화를 노출합니다.ViewModel 은 모델의 데이터의 실제 상태 인 과 대조적으로 데이터의 개념적 상태로 비유됩니다. [7]

+0

이것은 모두 좋은 일이지만 일반적인 저장소와 작업 패턴의 작동 방식에 대해 궁금합니다. – TIHan

1

UOW의 메소드를 두 개 이상 호출 할 수 있습니다.

그런 다음 필요한 모든 데이터를 viewmodel 생성자에 전달합니다. (뷰 모델로 Uow를 전달하면 정말 나쁜 것처럼 들린다)

컨트롤러에 UoW 등의 메소드를 많이 호출해야하는 복잡한 '로직'이 필요한 경우 다른 리포지토리 또는 비즈니스 로직 전용 레이어를 만드는 것을 고려해야합니다. 모든 열심히하고 당신의 컨트롤러에서 전화처럼

SomeClass something = Uow.BLGoodName.DoSomeFancyStuff(params ..) 
ViewData.model = new ControllerActionViewModel(something); 
Return View(); 
관련 문제