MVC3 - ViewModels и функциональность контроллера: предлагаемые шаблоны проектирования - PullRequest
2 голосов
/ 08 мая 2011

Я создал простой сайт для ввода заявок на основе MVC3 для приложения, которое менее пригодно для использования в колл-центре, и пытаюсь реорганизовать свой прототип, чтобы лучше придерживаться шаблонов проектирования, отчасти для того, чтобы сделать его более удобным для технического обслуживания в будущем, но в основном для обучения упражнение. Представление, ориентированное на пользователя, представляет собой форму, состоящую из базовой пользовательской информации в дополнение к нескольким панелям, позволяющим выбирать различные типы ресурсов. Каждый тип ресурса (оборудование, программное обеспечение и т. Д.) Отображается одинаково: с использованием двойных фильтруемых списков с кнопками добавления / удаления, необязательной текстовой области «обоснование», которая условно отображается, если запрашиваемый ресурс требует обоснования, и общими комментариями. Я построил следующую ViewModel для отдельных панелей:

public class RequestableList
{
    // list of requestable items ids requiring justification
    private List<string> _restrictedItems = new List<string>();
    public List<string> RestrictedItems
    {
        get { return _restrictedItems; }
        set { _restrictedItems = value; }
    }

    // the key-value pairs from which to populate available items list
    private Dictionary<string, string> _availableItems = new Dictionary<string, string>();
    public Dictionary<string, string> AvailableItems
    {
        get { return _availableItems; }
        set { _availableItems = value; }
    }

    // item ids requested by user
    private List<string> _requestedItems = new List<string>();
    public List<string> RequestedItems
    {
        get { return _requestedItems; }
        set { _requestedItems = value; }
    }
}

В этом случае основная ViewModel состоит из нескольких списков RequestableLists:

public class SimpleRequestViewModel
{
    public UserInfo userInfo { get; set; }
    public RequestableList Software {get;set;}
    public RequestableList Hardware {get;set;}
    public RequestableList Access {get;set;}
    public string SoftwareAdditionalInfo { get; set; }
    public string HardwareAdditionalInfo { get; set; }
    public string AccessFileMailShare { get; set; }
    public string AccessAdditionalInfo { get; set; }
    public string SoftwareJustification { get; set; }
    public string HardwareJustification { get; set; }
    public string AccessJustification { get; set; }
    public string Comment { get; set; }
}

Я создал строго типизированное представление для SimpleRequestViewModel (и его варианта) и строго типизированный EditorTemplate для RequestableList, который связывает двойные списки, фильтрацию и jquery. Все рендеринг хорошо и работает, но код в настоящее время пахнет.

При публикации на контроллере, если модель действительна, я должен перевести ее в читаемое текстовое описание, чтобы создать новый тикет в приложении центра обработки вызовов. Неправильно, когда контроллер выполняет этот перевод в читаемый текст, но я сталкиваюсь с препятствиями, когда пытаюсь создать другой класс для перевода моделей представления.

  1. Проводятся только выбранные значения элемента, поэтому перед переводом запроса в текст необходимо сначала найти соответствующий текст для предоставленных значений (они требуются в описании). Контроллер в настоящее время является единственным объектом, который имеет доступ к модели данных центра обработки вызовов для этого поискового запроса.
  2. Существует 2 аналогичных модели представления, содержащие различные комбинации списков запросов, поэтому любой переводчик должен иметь возможность переводить различные комбинации. У одного есть только аппаратное и программное обеспечение, у другого может быть аппаратное и еще несколько списков запросов.

Я рассмотрел переопределение ToString () непосредственно в ViewModel, но мне там не понравилась эта бизнес-логика (условное отображение), и опять же, после публикации ViewModel не содержит текста для выбранных элементов в списке, поэтому потребуется доступ к модели данных. Преобразование опубликованных значений в текст в том виде, в котором оно в данный момент обрабатывается в контроллере, пахнет так же, как в операторе switch. Контроллер принимает каждый опубликованный список RequestableList и заполняет исходные поля «Доступные», прежде чем создает новое описание заявки.

switch (requestCategory)
{
    case RequestableCategory.Software:
        itemList = sde.GetSoftware();
        break;
    case RequestableCategory.Hardware:
        itemList = sde.GetHardware();
        break;
    case RequestableCategory.Access:
        itemList = sde.GetAccess();
        break;
    case RequestableCategory.Telecom:
        itemList = sde.GetTelecom();
        break;
    default:
        throw new ArgumentException();
}

Итак, мой вопрос (ы):

  1. Какие шаблоны и методы вы бы порекомендовали для выполнения размещенной модели представления в перевод описания билета?
  2. Как вы обычно решаете проблему «только значения постов» с полями выбора, когда вам нужен текст и значение?
  3. Есть ли лучший способ для меня подойти к этой проблеме?

Опять же, я надеюсь, что это для меня опыт обучения, и я более чем готов предоставить дополнительную информацию или описание, если это необходимо.

1 Ответ

1 голос
/ 08 мая 2011

Несколько предложений:

  1. Абстрагируйте логику, которая делает передачу в колл-центр в свой собственный класс.Предоставьте (от контроллера) все зависимости, необходимые для доступа к базе данных колл-центра.Есть разные методы для обработки различных типов моделей представлений с использованием перегрузки.Предположительно описания поступают из БД, поэтому вы можете извлечь описание из БД на основе значения в этом классе.Этот класс также может взять на себя ответственность за построение моделей представления для действий отображения.Обратите внимание, что с этим шаблоном класс может взаимодействовать с БД напрямую, через хранилище или даже через веб-службы / API.

  2. Используйте шаблон хранилища, который реализует некоторое кэширование, если производительностьпроблема при поиске описания из БД во второй раз.Я подозреваю, что этого не произойдет, если ваш колл-центр не очень большой, но это место для оптимизации логики запросов.Хранилище может быть тем, что контроллер передает классу представления.

  3. Если вам не нужно обращаться к БД непосредственно в контроллере, рассмотрите возможность передачи класса посредника как зависимостинапрямую.

Может выглядеть так:

private ICallCenterBroker CallCenterBroker { get; set; }

public RequestController( ICallCenterBroker broker )
{
   this.CallCenterBroker = broker;
   // if not using DI, instantiate a new one
   // this.CallCenterBroker = broker ?? new CallCenterBroker( new CallCenterRepository() );
}

[HttpGet]
public ActionResult CreateSimple()
{
    var model = this.CallCenterBroker.CreateSimpleModel( this.User.Identity.Name );
    return View( model );
}


[HttpPost]
public ActionResult CreateSimple( SimpleRequestViewModel request )
{
    if (Model.IsValid)
    {
       var ticket = this.CallCenterBroker.CreateTicket( request );
       // do something with ticket, perhaps create a different model for display?
       this.CallCenterBroker.SubmitTicket( ticket );
       return RedirectToAction( "index" ); // list all requests?
    }
    return View();
}
...