- структуру папок функций (см. https://medium.com/c2-group/simplifying ... 13cff2d28c)
- архитектуру вертикального среза (см. https://jimmybogard.com/vertical-slice-architecture/). Фактически, я буду использовать шаблон CQRS с использованием библиотеки MediatR.
Код: Выделить всё
Features
Feature 1
XXXView.razor : the view
XXXView.razor.cs : the partial class
XXXView.razor.queries.cs : contains the queries (ex : GetCustomer) used by the view
XXXView.razor.commands.cs : contains the commands (ex : SaveCustomer) used by the view
Feature 2
Приведенный ниже код является примером того, что я бы сделал без использования ViewModel.
Код: Выделить всё
public partial class UserEditView : EditableComponentBase
{
[Parameter]
public long? Id { get; set; }
[Required]
public string Name { get; set; }
protected override async Task OnInitializedAsync()
{
if (this.Id.HasValue)
{
UserEntity user = await Mediator.Send(new GetUserQuery(this.Id.Value));
this.Name = user.Name;
this.Title = $"Change info of {user.Name}";
}
else
{
this.Title = "New user";
}
await base.OnInitializedAsync();
}
protected override async Task Save()
{
UserEntity user = this.Id.HasValue ? await Mediator.Send(new GetUserEditViewQuery(this.Id.Value)) : new UserEntity();
user.Nom = this.Name;
await Mediator.Send(new SaveUserCommand(user));
Close();
}
}
Приведенный ниже код представляет собой пример того, что я буду делать, если буду использовать ViewModel.
Код: Выделить всё
public partial class UserEditView : EditableComponentBase
{
[Parameter]
public long? Id { get; set; }
public UserViewModel User { get; set; } = new UserViewModel();
protected override async Task OnInitializedAsync()
{
if (this.Id.HasValue)
{
this.User = await Mediator.Send(new GetUserEditViewQuery(this.Id.Value));
this.Title = $"Change info of {this.User.Name}";
}
else
{
this.Title = "New user";
}
await base.OnInitializedAsync();
}
protected override async Task Save()
{
await Mediator.Send(new SaveUserCommand(user));
Close();
}
}
Как видите, разница, если бы я не использовал ViewModel, заключалась в том, что представление:
- само определяло поля, которые будут отображаться (без использования ViewModel)
- получило данные с помощью запроса, который возвращает здесь объект (но который может возвращать что-то еще, если необходимо) затем используйте его для установки переменных.
- преобразуйте переменные в сущность (или другой объект, если необходимо) и вызовите команду для сохранения информации.
=> это очень похоже на то, как я разрабатываю настольное приложение.
ОБНОВЛЕНИЕ
@Henk Holterman: я меняю GetUserQuery из примера 2 от GetUserEditViewQuery
@Ben Sampica: Во-первых, спасибо за ваш ответ.
Если я вас правильно понял,
В случае использования «Изменение информации о пользователе» ViewModel (UserEditViewModel) будет содержать всю информацию, необходимую для редактирования пользователя.
В случае использования «Просмотр информации о пользователе» ViewModel (UserViewViewModel: не очень приятно, но...) будет содержать всю информацию, необходимую для просмотра пользователя (которая может отличаться от страницы изменения).
=> запросы разные и поэтому возвращают разные модели представления.
Я понял, и это имеет смысл.
Но существует ли только одна модель представления на странице или я могу использовать более одной?
Действительно, в некоторых случаях страницы содержат список с кнопкой, которая позволяет пользователю добавить элемент в этот список.
/>Для меня добавление элемента в список вызывает новый запрос, который добавляет элемент в базу данных, а затем список обновляется.
Во многих примерах я вижу, как люди создают свойство в ViewModel страницы (скажем, UserEditViewModel) и заполняют его в основном запросе (скажем, GetUserEditViewQuery), что здесь на самом деле невозможно.
Если бы мне пришлось это сделать, я бы обязательно сделал что-то вроде этого:
Код: Выделить всё
this.List = await Mediator.Send(new GetListForUserEditViewQuery());
this.User = await Mediator.Send(new GetUserEditViewQuery());
Подробнее здесь: https://stackoverflow.com/questions/658 ... erver-side
Мобильная версия