ここではクエリとコマンドは引き続き別個のものと見なされますか?
はい、通常はコマンドを実行し、この操作が実行された後にUIを更新する必要がある場合は、新しい情報を取得するためのクエリを実行します。例がこれを明確にするでしょう。
特定の領域に特定のガードを割り当てるとします。コマンド(DTOのみ)が必要とする唯一の情報は、ガードのId
とエリアのId
です。関連付けられたCommandHandler
は、これを処理するためのすべてのタスクを実行します。そのガードを他のエリアから削除し、利用不可能なものとして予約してください。
あなたのUIは変更を表示したいでしょう。UIにはおそらく、すべてのガードとその割り当てられた領域に関する何らかの種類のリストがあります。このリストには、List<GuardWithAreaInformationDto>
を返す単一のGetActiveGuardsAndAreaQuery
が入力されます。このDTO
には、すべてのガードに関するすべての種類の情報を含めることができます。アトミックコマンド処理は、UI情報のわずかに異なる更新を必要とする類似しているが若干異なるUIから非常によく使用される可能性があるため、コマンドからこの情報を返すことは、懸念を明確に分離するものではありません。
ログイン試行など。それはクエリかコマンドですか?
IMOログイン試行ではありません。これは、クロスカッティングの問題であり、データが安全な接続の背後に隠れているという実装の詳細です。しかし、アプリケーションはこの詳細には関係してはいけません。 WebApiサービスをホストすることができる別の顧客とWindows Authentication
を使用できるActive Directory
ドメインのアプリケーションを使用することを検討してください。その場合、ユーザーは自分のマシンにログインするだけで、セキュリティは通信中にクライアントとサーバーのOSによって処理されます。
AuthenticateToWebApiServiceCommandHandlerDecorator
を使用すると、これを参照しているパターンを使用すると、ユーザーにモーダルフォームで質問したり、設定ファイルから読み込んだりするなど、ログイン資格情報がサービスに役立つようにすることができます。 。
標準の種類のQuery
を実行すると、資格情報が正常に実行されているかどうかを確認できます。アプリケーションには常にCheckIfUpdateIsAvailableQuery
などが必要です。照会が成功すると、ログイン試行は成功し、それ以外の場合は失敗しました。
コマンドハンドラからvoidが返された場合、ユーザ作成要求が成功したかどうかをプレゼンタにどのように伝えますか?
void
は何も返されませんが、これは実際には当てはまりません。なぜなら、何らかの例外(明確なメッセージが何が間違っているか)で失敗しなければ、成功したはずだからです。
上記のブログ記事の@dotnetjunkieには、コマンドから情報を返す方法が記載されていますが、投稿の上にコメントが追加されています。
要約すると、失敗したコマンドから明確な例外を投げる。これをうまく処理するために、抽象クライアント側の余分なレイヤーを追加することができます。一日の終わりに
public interface IPromptableCommandHandler<TCommand>
{
void Handle(TCommand command, Action succesAction);
}
public class PromptableCommandHandler<TCommand> : IPromptableCommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> commandHandler;
public PromptableCommandHandler(ICommandHandler<TCommand> commandHandler)
{
this.commandHandler = commandHandler;
}
public void Handle(TCommand command, Action succesAction)
{
try
{
this.commandHandler.Handle(command);
succesAction.Invoke();
}
catch (Exception)
{
MessageBox.Show("An error occured, please try again.");
// possible other actions like logging
}
}
}
// use as:
public void SetGuardActive(Guid guardId)
{
this.promptableCommandHandler.Handle(new SetGuardActiveCommand(guardId),() =>
this.RefreshGuardsList());
}
、任意のUIタスクのための(例えば:代わりに別のプレゼンターに直接commandhandlerを注入するあなたは、コンパイル時に1つだけ開いている一般的な実装を持っているIPromptableCommandHandler
を注入することができますユーザーの作成リクエスト)あなたはリサイズクライアントベースのクエリ/コマンドだけでなく、その端にリクエストを処理し、コマンド/クエリのウェブAPIサービスのバージョンを持ってしまうこと、それが終わるのでしょうか?
いいえ!
クライアント側あなたは、単にタスクがWEBAPIサービスにコマンドDTOを通過させることである単一のオープンジェネリックCommandHandlerProxy
を作成する必要があります。 Writing Highly Maintainable WCF Services非常にうまくこれを処理するサーバー側のアーキテクチャについて説明します。別のフォローアップあなたが読むべきサービス側アーキテクチャの
。リンクされたプロジェクトには、WebApiの実装も含まれています。
リックの答えはスポット上にあります。私はそれに追加するものは何もありません。 – Steven