Я понимаю, что «правильная» структура для разделения интересов в MVC состоит в том, чтобы иметь модели представления для структурирования ваших представлений и отдельные модели данных для сохранения в выбранном вами репозитории. Я начал экспериментировать с MongoDB и начинаю думать, что это может не применяться при использовании базы данных без схемы в стиле NO-SQL. Я хотел представить этот сценарий сообществу stackoverflow и узнать, что все думают. Я новичок в MVC, поэтому для меня это имело смысл, но, возможно, я что-то упускаю из виду...
Вот мой пример для этого обсуждения: когда пользователь хочет отредактировать свой профиль, он переходит к представлению UserEdit, в котором используется модель UserEdit, представленная ниже.
public class UserEditModel
{
public string Username
{
get { return Info.Username; }
set { Info.Username = value; }
}
[Required]
[MembershipPassword]
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.Password)]
[DisplayName("Confirm Password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Required]
[Email]
public string Email { get; set; }
public UserInfo Info { get; set; }
public Dictionary<string, bool> Roles { get; set; }
}
public class UserInfo : IRepoData
{
[ScaffoldColumn(false)]
public Guid _id { get; set; }
[ScaffoldColumn(false)]
public DateTime Timestamp { get; set; }
[Required]
[DisplayName("Username")]
[ScaffoldColumn(false)]
public string Username { get; set; }
[Required]
[DisplayName("First Name")]
public string FirstName { get; set; }
[Required]
[DisplayName("Last Name")]
public string LastName { get; set; }
[ScaffoldColumn(false)]
public string Theme { get; set; }
[ScaffoldColumn(false)]
public bool IsADUser { get; set; }
}
Заметили, что класс UserEditModel содержит экземпляр UserInfo, который наследуется от IRepoData? UserInfo — это то, что сохраняется в базе данных. У меня есть общий класс репозитория, который принимает любой объект, наследующий форму IRepoData, и сохраняет его; поэтому я просто звоню Repository.Save(myUserInfo)
и все готово. IRepoData определяет _id (соглашение об именовании MongoDB) и временную метку, поэтому репозиторий может обновляться на основе _id и проверять наличие конфликтов на основе временной метки и любых других свойств, которые объект только что сохранил в MongoDB. Представление, по большей части, просто нужно использовать @Html.EditorFor
, и мы готовы к работе! По сути, все, что нужно только представлению, входит в базовую модель, все, что нужно только репозиторию, просто получает аннотацию [ScaffoldColumn(false)]
, а все остальное является общим между ними. (Кстати, имя пользователя, пароль, роли и адрес электронной почты сохраняются в поставщиках .NET, поэтому их нет в объекте UserInfo.)
У этого сценария есть два больших преимущества...
Я могу использовать меньше кода, поэтому его легче понять, быстрее разрабатывать и легче поддерживать (на мой взгляд).
Я могу рефакторить за секунды... Если мне нужно добавить второй адрес электронной почты, я просто добавляю его в объект UserInfo — он добавляется в представление и сохраняется в репозитории, просто добавляя одно свойство объекта. Поскольку я использую MongoDB, мне не нужно изменять схему моей базы данных или возиться с какими-либо существующими данными.
При такой настройке есть ли необходимость делать отдельные модели для хранения данных? Каковы, по вашему мнению, недостатки этого подхода? Я понимаю, что очевидными ответами являются стандарты и разделение интересов, но можете ли вы придумать какие-либо примеры из реального мира, которые продемонстрируют некоторые из головных болей, которые это вызовет?
Также стоит отметить, что я работаю в команде всего из двух разработчиков, поэтому легко увидеть преимущества и не заметить отклонение от некоторых стандартов. Как вы думаете, работа в небольшой команде имеет значение в этом отношении?