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.
LoginYeni 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 modelve sonra CommandResultbir eylem sonrası filtre işlemek için . As tartışılan burada .
Bunun bir uygulaması şöyle CommandResultolabilir
public interface ICommandResult
{
bool IsSuccess { get; }
bool IsFailure { get; }
object Result { get; set; }
}
Ancak bu, Logineylemdeki 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 ( returnUrlFromQuery) 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?