[asp core mvc] Dto, viewmodele pomiędzy warstwą prezentacji a aplikacji.

0

Mam projekt podzielony w następujący sposób:

  • Core
    • Domain
    • Application
  • Persistence
  • Presentation
    • WebApi
    • Razor
    • Blazor

Cała logika znajduje się w Core, wszystkie projekty z prezentacji posiadają referencje tylko do Application. Korzystam z rozdzielenia przypadków użycia na commands, queries.

Teraz przykładowo chcę stworzyć nowego klienta, więc definiuję komendę:

public class CreateCustomerCommand : IRequest<int>
{
	public string Name { get; set; }
	public int MembershipTypeId { get; set; }
	public bool IsSubscribedToNewsletter { get; set; }
	public DateTime? Birthdate { get; set; }
}

I tu pojawia się mój problem, mianowicie chcę, wybrać MembershipType z rozwijanej listy, żeby móc to zrobić w kontrolerze pobieram dostępne opcje i przesyłam je do widoku:

public class CustomersController : Controller
{
	public async Task<IActionResult> Create()
	{
		var membershipTypes = await _mediator.Send(new GetMembershipTypesQuery());

		return View(membershipTypes);
	}
}

public class GetMembershipTypesQueryHandler : IRequestHandler<GetMembershipTypesQuery, IEnumerable<MembershipTypeDto>>
{
	public async Task<IEnumerable<MembershipTypeDto>> Handle(GetMembershipTypesQuery request, CancellationToken cancellationToken)
	{
		return await _context.MembershipTypes
			.Select(MembershipTypeDto.Projection)
			.ToListAsync(cancellationToken);
	}
}

Ale w tym przypadku nie mam do czego bindować pól z formularza, więc tworzę viewmodel:

public class CreateCustomerViewModel
{
	public CreateCustomerCommand Command { get; set; }
	public IEnumerable<MembershipTypeDto> MembershipTypes { get; set; }
}

public class CustomersController : Controller
{
	public async Task<IActionResult> Create()
	{
		var membershipTypes = await _mediator.Send(new GetMembershipTypesQuery());

		var vm = new CreateCustomerViewModel { MembershipTypes = membershipTypes };

		return View(vm);
	}
}
  1. Czy tworzenie viewmodeli w kontrolerze jest dobrą opcją? Początkowo myślałem, żeby je zwracać z Application ale nie wiem jak by to miało wyglądać np. dla CreateCustomerViewModel, utworzyć query, które mi zwróci vm, nie widzę w tym sensu szczególnie, że jeśli posiadam API to tam nie potrzebuję viewmodeli.
  2. Obecnie viewmodele znajdują się w warstwie prezentacji co powoduje, że dla każdego projektu muszę tworzyć ich kopię czy to jest dobre podejście czy może przenieść je do Application lub stworzyć nowy projekt i dzielić pomiędzy wszystkie projekty z warstwy prezentacji?
0

Nie wiem czy to zadziała ale ja bym zrobił widok z modelem CreateCustomerCommand. A membershipTypes przekazywał do widoku np za pomocą jakiegoś ViewBag czy ViewData. Raczej nie duplikowałbym ViewModeli. No i teraz jeśli masz różne projekty (API, MVC) to prezentacje danych (ViewModele) wrzuciłbym do osobnego projektu np jakiś Common. I to zwracał z Application. Takie moje zdanie.

0

Ja do końca nie rozumiem na czym polega problem, ale odpowiadając na pytania:

  1. View modele należą do warstwy widoku więc tak, tam należy je tworzyć. Żeby było ładnie i czysto można użyć extensions methods.

  2. Każdy Twój projekt to inna aplikacja UI, więc moim zdaniem powinna posiadać własne view modele. Po prostu traktował bym je tak jakby równie dobrze były w oddzielnych solucjach.

1 użytkowników online, w tym zalogowanych: 0, gości: 1