2013-07-08 3 views
2

ASP.NET MVC 3 응용 프로그램이 있습니다.ASP.NET MVC 디자인 패턴 서비스 모범 사례

은 내가 Model, ViewModel, View, Controller 있습니다.

나는 IOC의로 Ninject를 사용합니다.

ControllerViewModel을 사용하여 데이터를 View으로 전달합니다.

나는 ViewModel에서 정보를 받아이를 조작하기 위해 데이터베이스에 대해 그것을 쿼리 Service의 (콘크리트 및 인터페이스 유형)를 사용하기 시작했습니다.

내가 사용할 수 설정 ViewModel에 동일한 Service? 아니면 이것은 디자인 패턴의 곡식에 맞습니까?

e.e. 레이어에서 ViewModel을 추상화 할 수 있습니까?

시나리오

시나리오입니다; 내 Model 다른 Models에 대한 참조를 많이 가지고, 그래서 설치가 장황의 컨트롤러에서 ViewModel, 내가 느낄 때 Controller 너무 많이하고있다. 같을 것이다

var vm = _serviceProvider.SetupViewModel(Guid model1Id, Guid model2Id, /*etc..*/)

그리고 ServiceProvider에서 SetupViewModel 기능 : 그래서 난 그냥 뭔가를 할 수 있도록하려면

public MyModelViewModel SetupViewModel(Guid model1Id, Guid model2Id, /*etc...*/) 
{ 
    var vm = new MyModelViewModel(); 
    var model1 = _repository.Model1s.FirstOrDefault(x => x.Id.Equals(model1Id)); 
    var model2 = _repository.Model2s.FirstOrDefault(x => x.Id.Equals(model2Id)); 
// etc.... 

    vm.Model1 = model1; 
    vm.Model2 = model2; 

    return vm; 
} 

이렇게 나는 또한 일부 null 조건을 추가 할 수 있습니다 뿐만 아니라, 내 Controller 정말 정말 큰 만들기에 대해 걱정하지!

내가 작성/편집 작업 1 ViewModel를 사용합니다. 다른 곳에서는 ViewModel을 재사용하지 않습니다.

+0

특정 아키텍처에 대한 정보를 조금 더 제공하는 것이 어떻습니까? 아마도 당신이하려는 것을 설명하는 간략한 코드 샘플일까요? –

+0

약간의 질문을 편집했지만 코드를 넣지 않았습니다 –

+1

ViewModels를 재사용하고있는 것처럼 들립니다. – Phill

답변

5

도메인 모델을 반환하고 컨트롤러의 ViewModel에 매핑하도록합니다.

이 방법 당신은 데스크톱 및 예를 들어 모바일보기 위해 여러 ViewModels과 서비스 방법을 사용할 수 있습니다.

도메인 모델을 사용하는 ViewModel에서 생성자를 생성하여 AutoMapper이 직접 노력하거나 직접 할 수 있습니다.

도메인 모델 :

public class Customer 
{ 
    public int Id { get; set; } 

    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public string Telephone { get; set; } 

    public string Email { get; set; } 

    public virtual ICollection<Order> Orders { get; set; } 
} 

뷰 모델 :

public class CustomerWithOrdersModel 
{ 
    public CustomerWithOrdersModel(Customer customer) 
    { 
     Id = customer.Id; 
     FullName = string.Format("{0}, {1}", customer.LastName, customer.FirstName); 
     Orders = customer.Orders.ToList(); 
    } 

    public int Id { get; set; } 

    public string FullName { get; set; } 

    public IEnumerable<Order> Orders { get; set; } 
} 

EDIT : AutoMapper 예 :

에서 매핑을 함유 AutoMapper 프로필 CustomerCustomerWithOrdersModel A와 :

public class ViewModelProfile : Profile 
{ 
    public override string ProfileName 
    { 
     get { return "ViewModel"; } 
    } 

    protected override void Configure() 
    { 
     CreateMap<Customer, CustomerWithOrdersModel>() 
      .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => string.Format("{0}, {1}", src.LastName, src.FirstName))) 
      .ForMember(dest => dest.Orders, opt => opt.MapFrom(src => src.Orders.ToList())); 
    } 
} 

Id은 규칙에 따라 매핑됩니다. ViewModelProfile에 대한

확장 방법 :

public static class ViewModelProfileExtensions 
{ 
    public static CustomerWithOrdersModel ToModel(this Customer customer) 
    { 
     return Mapper.Map<CustomerWithOrdersModel>(customer); 
    } 

    public static Customer ToEntity(this CustomerWithOrdersModel customerWithOrdersModel) 
    { 
     return Mapper.Map<Customer>(customerWithOrdersModel); 
    } 
} 

컨트롤러 조치 : CustomerWithOrdersModel에서 Customer에 매핑을 만드는 경우

public ActionResult Details(int customerId) 
{ 
    Customer customer = _customerService.GetById(customerId); 
    CustomerWithOrdersModel customerWithOrders = customer.ToModel(); 
    return View(customerWithOrders); 
} 

, 당신은 도메인 모델로 다시 매핑 할 customerWithOrdersModel.ToEntity()을 사용할 수 있습니다 . 그것은

그게 전부! ViewModel에서 Customer 도메인 모델을 사용하여 생성자를 제거 할 수 있습니다.

+0

'AutoMapper'를 사용하는 것이 더 나은 이유를 보여주는 예제를 제공해 주시겠습니까? 현재'ViewModels'을 만들고 사용하는 현재의 방법은 여러분이 제시하는 것보다 훨씬 낫습니다. 복잡한'비즈니스 모델 '을 가지고있을 때'ViewModels'와'Controllers'를 장황하게하고 싶습니다. –

+0

@ No1_Melman이 업데이트되었습니다. 내 대답. –

+0

꽤 멋지다. AutoMapper를 사용하는 모든 복잡함을 발견하는 새로운 프로젝트를 시작해야 할 것이다. –

1

당신이 자신의 프로젝트와 뷰 모델을 가지고 매핑을 처리하고 서비스 계층에서보기 모델의 반환, 내가 그 잘못 아무것도 볼 경우. 우려 사항을 분리하기 위해 매핑을 처리하는 다른 구성 요소가 항상있을 수 있습니다.

+0

그러면 구체적인 구현과 인터페이스 구현을 가진 또 다른 서비스가 될 것입니까? –

+0

예. 그렇게하면 컨트롤러에 주입 할 수 있고 단위 테스트를 도울 수 있습니다. 독립 실행 형 서비스를 테스트 할 수 있고 매번 테스트 할 때마다 동일한 방법이 컨트롤러 중 하나에서 사용된다는 점에 대해 걱정할 필요가 없습니다. 컨트롤러 테스트에서는 서비스를 조롱 할 수 있습니다. – Maess

+0

질문에 몇 가지 정보를 추가했는데 여전히 답변과 일치합니까? –