최근 CQRS / MediatR을 살펴 보았습니다. 그러나 드릴 다운할수록 마음에 들지 않습니다. 아마도 나는 무언가 / 모든 것을 오해했을 것입니다.
따라서 컨트롤러를 이것으로 줄인다는 주장으로 시작됩니다.
public async Task<ActionResult> Edit(Edit.Query query)
{
var model = await _mediator.SendAsync(query);
return View(model);
}
얇은 컨트롤러 지침에 완벽하게 맞습니다. 그러나 오류 처리와 같은 매우 중요한 세부 사항은 생략합니다.
Login
새로운 MVC 프로젝트에서 기본 동작을 볼 수 있습니다
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation(1, "User logged in.");
return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning(2, "User account locked out.");
return View("Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
변환하면 실제 문제가 많이 발생합니다. 목표는 그것을 줄이는 것입니다
public async Task<IActionResult> Login(Login.Command command, string returnUrl = null)
{
var model = await _mediator.SendAsync(command);
return View(model);
}
이에 대한 한 가지 가능한 해결책 CommandResult<T>
은 a 대신 a 를 반환 한 후 사후 조치 필터 model
를 처리하는 것 CommandResult
입니다. 여기서 논의한 바와 같이 .
구현 중 하나 CommandResult
는 다음과 같습니다
public interface ICommandResult
{
bool IsSuccess { get; }
bool IsFailure { get; }
object Result { get; set; }
}
그러나 Login
여러 실패 상태가 있기 때문에 조치 에서 문제를 실제로 해결하지는 못합니다 . 이러한 추가 실패 상태를 추가 할 수 ICommandResult
있지만 이는 매우 부풀린 클래스 / 인터페이스의 시작입니다. SRP (Single Responsibility)를 준수하지 않는다고 말할 수도 있습니다.
또 다른 문제는 returnUrl
입니다. 이 return RedirectToLocal(returnUrl);
코드 조각이 있습니다. 어떻게 든 명령의 성공 상태에 따라 조건부 인수를 처리해야합니다. 나는 그것을 할 수 있다고 생각하지만 (ModelBinder가 FromBody와 FromQuery ( returnUrl
FromQuery) 인수를 단일 모델에 매핑 할 수 있는지 확실하지 않습니다 ). 어떤 종류의 미친 시나리오가 길을 떠날 수 있는지 궁금해 할 수 있습니다.
오류 메시지 반환과 함께 모델 검증도 더욱 복잡해졌습니다. 이것을 예로 들어
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
모델과 함께 오류 메시지를 첨부합니다. 이런 종류의 일은 모델이 필요하기 때문에 Exception
전략을 사용하여 수행 할 수 없습니다 ( here 제안 ). 아마도 모델을 얻을 수는 Request
있지만 매우 복잡한 프로세스 일 것입니다.
그래서이 "간단한"액션을 변환하는 데 어려움을 겪고 있습니다.
입력을 찾고 있습니다. 나는 여기에 완전히 잘못되어 있습니까?