私は最近CQRS / MediatRを調査しています。しかし、ドリルダウンすればするほど、それが好きではなくなります。おそらく私は何か/すべてを誤解しました。
だから、これをあなたのコントローラーをこれに減らすと主張することから、それは驚くほど始まります
public async Task<ActionResult> Edit(Edit.Query query)
{
var model = await _mediator.SendAsync(query);
return View(model);
}
Thin Controllerのガイドラインに完全に適合します。ただし、非常に重要な詳細-エラー処理は省略します。
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);
}
これに対する1つの可能な解決策CommandResult<T>
は、aの代わりにを返し、model
その後CommandResult
、ポストアクションフィルターで処理することです。ここで説明したように。
の1つの実装は次のCommandResult
ようになります
public interface ICommandResult
{
bool IsSuccess { get; }
bool IsFailure { get; }
object Result { get; set; }
}
ただし、Login
複数の障害状態があるため、実際のアクションの問題は解決しません。これらの追加の障害状態を追加することもできますがICommandResult
、それは非常に肥大化したクラス/インターフェイスの素晴らしい出発点です。単一責任(SRP)に準拠していないと言う人もいるかもしれません。
別の問題は、returnUrl
です。このreturn RedirectToLocal(returnUrl);
コードがあります。どういうわけか、コマンドの成功状態に基づいて条件付き引数を処理する必要があります。私はそれができると思いますが(ModelBinderがFromBodyとFromQuery(returnUrl
FromQuery)引数を単一のモデルにマッピングできるかどうかはわかりません)。どのようなクレイジーなシナリオが今後発生する可能性があるのか疑問に思うだけです。
モデルの検証も、エラーメッセージを返すことに伴い、より複雑になりました。これを例に取ります
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
モデルとともにエラーメッセージを添付します。この種のことは、モデルを必要とするため、Exception
戦略を使用して行うことはできません(ここで提案されています)。おそらくモデルを取得できますRequest
が、非常に複雑なプロセスになります。
全体として、この「単純な」アクションを変換するのに苦労しています。
入力を探しています。私はここで完全に間違っていますか?