Является ли создание класса BaseViewData свойством класса BaseController - плохая идея?

Каждый класс контроллера в моем проекте является производным от базового класса контроллера, метко названного BaseController.

Все данные представления содержатся в классе с именем BaseViewData (который в будущем может стать базовым контроллером для более конкретных классов данных представления).

Я создал свойство BaseViewData для BaseController, поскольку каждому контроллеру требуется доступ к данным внутри строго типизированных данных базового представления (и BaseController выполняет некоторую работу по предварительному заполнению некоторых свойств BaseViewData).

Я сделал это потому, что:

  1. Если бы я когда-либо изменил свойство, я бы получил проверку ошибок времени компиляции, чтобы быстрее разрешить неработающий код.

  2. Практикуя DRY, мне удалось консолидировать МНОГО кода, который ранее был разбросан по каждому контроллеру.

Однако это первая попытка сделать это. Так что я мог упустить из виду проблему, готовясь вскинуть свою уродливую голову. Так:

Является ли плохой идеей превращать класс BaseViewData в свойство класса BaseController? Если да, то почему?

Обновление 1:

Мой BaseController выглядит примерно так (есть еще кое-что, но это должно прояснить суть):

public class BaseController
{
  public string Language {get; set;}
  public string Locale {get; set;}
  public BaseViewData Data {get; set;}

  protected override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    var l = (RouteData.Values["language"] != null) ? RouteData.Values["language"].ToString() : "en";
    if (l.ToLower().Contains("en"))
    {
      l = "en";
    }
    else
     l = "ja";

    Data.Language = l;
  }
}

Мои BaseViewData выглядят так (опять же, есть еще ...):

public class BaseViewData
{
  public string Language {get;set;}
  public string Locale {get;set;}
  public bool IsOwner {get;set;}
  public string Menu1 {get;set;}
  public string Menu2 {get;set;}
  public string Menu3 {get;set;}

  public IPagedList<TYPE> ListOfTYPE {get;set;}
  etc...
}

person Chaddeus    schedule 17.12.2009    source источник
comment
Интересная идея. Я мог бы сам использовать IViewData с BaseController. Я бы подумал, что мой IViewData будет просто общим DTO без таких функций, как: UserId, UserName и IsLoggedIn или что-то в этом роде ... Мне было бы интересно посмотреть, что у вас есть в ваших BaseViewData.   -  person rball    schedule 18.12.2009


Ответы (3)


Для единственного сайта, над которым я когда-либо работал в ASP.NET MVC, это именно то, что мы сделали. Приятным моментом в этом также было то, что мы могли хранить значения в классе BaseViewData, которые были необходимы на главной странице. Поскольку каждое представление имело экземпляр некоторых производных BaseViewData, мы могли безопасно использовать данные в BaseViewData на главной странице.

person BFree    schedule 17.12.2009
comment
Я тоже этим занимаюсь. Отлично работает, просто надеюсь, что не собираюсь выращивать монстра. : D - person Chaddeus; 18.12.2009

Компонент меню вашей идеи может не понадобиться, с бета-версией ASP.NET MVC 2 теперь вы можете использовать Http.RenderAction для вызова действия контроллера непосредственно из представления (например, действие BuildMenu, которое извлекает элементы меню из репозитория и возвращает частичное представление.

См. Дополнительную информацию Haacked ...

Кроме того, для более простого содержимого, такого как язык / локаль, это может не потребоваться, если вы используете поставщик профиля ASP.NET (доступный как через контроллер, так и через представление).

person Mark van Proctor    schedule 18.12.2009
comment
У вас есть пример веб-сайта на основе ASP.NET MVC, использующего таким образом поставщик профиля? - person Chaddeus; 18.12.2009
comment
Мне нравится идея возможности вызывать действие напрямую через RenderAction ... хм ... - person Chaddeus; 18.12.2009
comment
Я думаю, что ASP.NET MVC 2 может вызвать серьезное переписывание моего приложения ... но в конечном итоге оно того стоит. - person Chaddeus; 18.12.2009
comment
Что касается использования Profile Provider, существует множество документов MSDN о том, как его использовать, однако у вас нет доступа к строго типизированному Profile. [Название свойства] непосредственно в контроллере. Однако я создал ProfileCommon: ProfileBase, который может использовать провайдер профиля asp.net по умолчанию и который обеспечивает строго типизированный доступ в контроллере. Я также создаю свои контроллеры для наследования от BaseController, где я получаю профиль, используя ProfileBase.Create (имя пользователя) как ProfileCommon. Я нашел эти инструкции по stackoverflow ... - person Mark van Proctor; 18.12.2009
comment
К сожалению, VS2010 не поставляется с бета-версией MVC 2, он поставляется с MVC 2 Preview 2 .... :( и поэтому в нем нет методов Html.RenderAction - person Mark van Proctor; 18.12.2009
comment
VS2010 отправлен? Это только бета-версия с веб-сайта VS. - person Chaddeus; 18.12.2009
comment
извините, бета-версия vs2010 не поставляется с бета-версией MVC 2 - person Mark van Proctor; 18.12.2009

ИМХО, вы создаете монстра.

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

Лучше использовать такие вещи, как RenderAction MVC2 или материал SubController из MVC Contrib, даже если это означает небольшое нарушение шаблона MVC.

Посмотрите на такой сайт, как CNN или даже Stackoverflow.com, у вас будет дюжина методов, прежде чем вы это узнаете.

person John Farrell    schedule 18.12.2009
comment
Это единственная проблема, о которой вы можете подумать? Это тоже было моей главной заботой, и я буду держать ее в голове во время разработки. Я единственный разработчик этого приложения, поэтому не беспокойтесь о том, что другие добавят что-то без моего ведома заранее. - person Chaddeus; 18.12.2009
comment
И, собственно, даже если бы он стал немного толстоватым - какой в ​​этом вред? Есть ли какое-то снижение производительности при передаче большого строго типизированного объекта viewdata (даже если многие свойства были пустыми?)? Просто любопытно ... спасибо. - person Chaddeus; 18.12.2009
comment
Вы нарушите принцип единой ответственности. Ваша базовая модель представления в конечном итоге будет отвечать за множество вещей. - person John Farrell; 18.12.2009
comment
Хорошая точка зрения. Что, если все, что он собирался делать, это хранить некоторые данные в свойствах? Другие классы будут делать работу по созданию данных, которые будут храниться в BaseViewData? - person Chaddeus; 18.12.2009