Son zamanlarda CQRS / MediatR'ı araştırdım. Ama daha fazla ayrıntıya inersem daha az hoşuma gider. Belki de bir şeyi / her şeyi yanlış anladım.
Bu yüzden kontrol cihazınızı buna indirgeyerek iddia ederek harika başlar
public async Task<ActionResult> Edit(Edit.Query query)
{
var model = await _mediator.SendAsync(query);
return View(model);
}
İnce kontrolör kılavuzuna mükemmel uyum sağlar. Ancak, hata işleme - oldukça önemli bazı ayrıntılar bırakır.
Login
Yeni bir MVC projesinden varsayılan eyleme bakalım
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);
}
Dönüştürme bize bir sürü gerçek dünya problemi sunuyor. Unutmayın, amaç
public async Task<IActionResult> Login(Login.Command command, string returnUrl = null)
{
var model = await _mediator.SendAsync(command);
return View(model);
}
Bunun olası bir çözümü bir CommandResult<T>
yerine bir döndürmek model
ve sonra CommandResult
bir eylem sonrası filtre işlemek için . As tartışılan burada .
Bunun bir uygulaması şöyle CommandResult
olabilir
public interface ICommandResult
{
bool IsSuccess { get; }
bool IsFailure { get; }
object Result { get; set; }
}
Ancak bu, Login
eylemdeki sorunumuzu gerçekten çözmez , çünkü birden fazla başarısızlık durumu vardır. Bu ekstra hata durumlarınıICommandResult
ancak bu çok şişmiş bir sınıf / arayüz için harika bir başlangıçtır. Tek Sorumluluk (SRP) ile uyumlu olmadığını söyleyebiliriz.
Başka bir sorun returnUrl
. Bu return RedirectToLocal(returnUrl);
kod parçamız var. Her nasılsa, komutun başarı durumuna dayalı koşullu argümanları ele almamız gerekir. Ben bu yapılabilirdi düşünüyorum olsa da (ModelBinder FromBody ve FromQuery ( returnUrl
FromQuery) bağımsız değişkenleri tek bir model eşleyebilirsiniz emin değilim ). Sadece ne tür çılgın senaryoların yoldan aşağıya gelebileceğini merak edebiliriz.
Model doğrulaması, geri dönen hata mesajlarıyla birlikte daha karmaşık hale gelmiştir. Bunu örnek olarak alalım
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
Modelle birlikte bir hata mesajı ekliyoruz. Bu tür bir şey Exception
( burada önerildiği gibi ) bir strateji kullanılarak yapılamaz çünkü modele ihtiyacımız var. Belki modeli alabilirsinizRequest
ama çok ilgili bir süreç olurdu.
Sonuçta bu "basit" eylemi dönüştürmekte zorlanıyorum.
Girdi arıyorum. Burada tamamen yanlış mıyım?