Проблема с поиском подходящего места для размещения Services / ViewModel в приложении MVC - PullRequest
2 голосов
/ 26 апреля 2011

У меня есть приложение S # arp MVC со следующими проектами / слоями:

  • Ядро (модель)
  • Данные
  • Веб (просмотр)
  • Контроллеры
  • Услуги

Один пример, показывающий проблему:
У меня есть модель Билет :

public class Ticket : Entity
{
     public virtual string Summary { get; set; }
     public virtual string Description { get; set; }       
     public virtual DateTime CreateOn { get; set; }        
     public virtual DateTime UpdatedOn { get; set; }
     public virtual User CreatedBy { get; set; }
     public virtual User AssignedTo { get; set; }
     public virtual Priority Priority { get; set; }        
     public virtual Status Status { get; set; }        
}

Он расположен в основном проекте ...

Для просмотра View Create (Ticket) мне нужен CreateTicketViewModel :

public class CreateTicketVM
{
     [Required(ErrorMessage = "Required.")]
     public string Summary { get; set; }

     [Display(Required(ErrorMessage = "Required.")]
     public string Description { get; set; }

     [Required(ErrorMessage = "Required.")]
     public int AssignedToId { get; set; }     

     [Required(ErrorMessage = "Required.")]
     public int PriorityId { get; set; }

     [Required(ErrorMessage = "Required.")]
     public virtual int StatusId { get; set; }      

     public IList<User> Users { get; set; }       
     public IList<Priority> Priorities { get; set; }
     public IList<Status> Status { get; set; }        
}

Он расположен в проекте контроллера...

Пока все хорошо ... Но в моем TicketController мне нужно заполнить все списки CreateTicketVM (выпадающие списки в View).

Итак, я создал TicketService :

public class TicketService : ITicketService
{       
     readonly IRepository<User> userRepository;
     readonly IRepository<Priority> priorityRepository;
     readonly IRepository<Status> statusRepository;
     ...     

     public CreateTicketVM CreateNewCreateTicketVM()
     {
         var _ticket = new CreateTicketVM();
         _ticket.Priorities = priorityRepository.GetAll();
         _ticket.Status = statusRepository.GetAll();
         _ticket.Users = userRepository.GetAll();
          _ticket.Categories = categoryRepository.GetAll();
          return _ticket;
     }
}

Он расположен в сервисном проекте ...

Проблема с интерфейсом ITicketService:

public interface ITicketService
{
    CreateTicketVM CreateNewCreateTicketVM();
}

Он находится в базовом проекте ... Но базовый проект не может включать проект контроллера (CreateTicketVM) ...

Итак, как мне справиться с этим?

Спасибо

Пол

Ответы [ 3 ]

7 голосов
/ 26 апреля 2011

Вместо того, чтобы помещать ваш метод CreateNewCreateTicketVM в ваш сервис, я бы создал для этого расширенный объект запроса в вашем проекте Controllers. Уровень услуг в этом случае касается только поведения.

Смотрите мой блог:

http://www.yellowfeather.co.uk/2011/03/enhanced-query-objects-with-sharp-architecture/

и отзыв Айенде:

http://ayende.com/Blog/archive/2011/04/01/code-review-sharparchitecture.multitenant.aspx

2 голосов
/ 27 апреля 2011

Крис прибил это.Используйте объект запроса для проецирования прямо в модель представления.

1 голос
/ 26 апреля 2011

Когда вы возвращаете ViewModel (или DTO, имя не имеет значения), заполненный списками ILists, предназначенными только для отображения в представлении, вы уже тесно связаны с вашим представлением с "семантической" точки зрения .

Разве вы не слишком продумали что-то здесь, что не может быть решено с помощью меньшего количества проектов, например:

  • Core: блоки инфраструктуры, которые можно использовать совместно с другими приложениями
  • MyApp: специальный код для вашего приложения, упорядоченный по пространствам имен
    • MyApp.Data
    • MyApp.Services (сервисные интерфейсы)
    • MyApp.Services.Implementations (если вы действительно хотите разделить)
  • MyApp.Web
    • MyApp.Web.Models
    • MyApp.Web.Controllers

MyApp.Web может быть проектом MVC или, если хотите, 2 проекта, одна библиотека c # с контроллерами и 1 проект MVC только с представлениями.

В этом случае, мне кажется, слишком сложно иметь сервисный слой для построения ViewModel. Это должно быть сделано в вашем контроллере или, что лучше, с помощью такого инструмента, как AutoMapper.

Уровень обслуживания должен иметь некоторые деловые обязанности: "может ли этот пользователь назначить билет этому в это точное время?" например.

Кроме того, у Айенде есть хороший пост в блоге об этом: http://ayende.com/Blog/archive/2011/03/16/architecting-in-the-pit-of-doom-the-evils-of-the.aspx

Не забудьте: ПОЦЕЛУЙ

...