これまでの検証への取り組みについて、ご意見をお聞かせください。私たちはまだ開発プロセスの初期段階にあるので、まだ変更できます。検証は、このアプリケーションとクライアントにとって非常に重要であるため、最適な方法を見つける必要があります。これまでに行ったことを説明しましょう...
さまざまなクライアントによって消費されるこのアプリケーションを構築しています。すべてのクライアントを管理しているわけではないため、すべてのレイヤーで検証するための厳格な要件があります。一部のクライアント アプリケーションは管理していますが、そのうちの 1 つは最大 100 人のユーザーが使用する WPF アプリケーションです。このアプリケーションから、ワークフローは次のようになります。
| Client | Backend Service |
ViewModel -> ClientRepository -> ServiceClient -> Service (WCF) -> ApplicationService -> DomainModel -> Repository -> Database
検証を実行するための候補として、以下を参照してください。
- クライアント: 必須フィールド、長さなどで UI をサポートするための ViewModel 検証。
- バックエンド: クライアントが常に 100% 有効な値を提供することに依存できないため、サービス リクエストの DTO 検証。
- バックエンド: ドメイン モデル エンティティの検証。エンティティが無効な状態になることは望ましくないため、各エンティティには、操作が実行されるときに異なるチェックが含まれます。
- バックエンド: 制約の失敗などのデータベース検証 (FK、一意性、長さなど)
クライアントの ViewModel 検証は非常に明白であり、私たち自身のクライアントにとっては、サービスに到達する前にできるだけ多くのエラーを修正する必要があります。ただし、私たちのサービスを消費する他のアプリケーションについて話すことはできません。最悪の場合を想定する必要があります。
サービス リクエストの DTO は、主にサード パーティのアプリケーションの場合と、弊社のクライアントでのミスについて検証する必要があります。リクエストが正しいことを確認することで、後でリクエストの処理中にエラーが発生するのを防ぐことができ、より効果的なサービスを確保できます。ViewModel の検証と同様に、これはさまざまなプロパティの必須フィールド、長さ、および形式 (電子メールなど) に帰着します。
Customer
ドメイン モデルのエンティティ自体は、常に完全に有効な属性/プロパティを持つことを保証する必要があります。エンティティを例として、このように実現しています。
public class Customer : Entity
{
private Customer() : base() { }
public Customer(Guid id, string givenName, string surname)
: this(id, givenName, null, surname) { }
public Customer(Guid id, string givenName, string middleName, string surname)
: base(id)
{
if (string.IsNullOrWhiteSpace(givenName))
throw new ArgumentException(GenericErrors.StringNullOrEmpty, "givenName");
if (string.IsNullOrWhiteSpace(surname))
throw new ArgumentException(GenericErrors.StringNullOrEmpty, "surname");
GivenName = givenName.Trim();
Surname = surname.Trim();
if (!string.IsNullOrWhiteSpace(middleName))
MiddleName = middleName.Trim();
}
}
これにより、属性が有効であることが保証されますが、CustomerValidator
クラスは Customer クラス全体を検証し、それが有効な状態にあり、有効な属性を持っているだけではないことを確認します。FluentValidationCustomerValidator
フレームワークを使用して実装されます。これは、顧客オブジェクトをデータベースにコミットする前に、アプリケーション サービスで呼び出されます。
これまでの私たちのアプローチについてどう思いますか?
私が少し心配しているのは、いたるところにスローされる例外の使用です。たとえばArgumentException
、上記の例だけInvalidOperationException
でなく、オブジェクトの現在の状態では許可されていないメソッドへの呼び出しの場合も同様です。
サービス リクエストの DTO が検証されているため、これらの例外がスローされることはめったにないことを願っています。たとえば、サービス リクエストの DTO が検証される場合、検証のどこかにエラーがない限り、引数の例外が発生することはありません。したがって、ドメイン モデルでのこれらの引数チェックは、追加のセキュリティ レイヤーとして機能すると言えます。InvalidOperationException
一方、クライアントが、現在の状態では利用できない Customer オブジェクトのメソッドを呼び出すサービス メソッドを呼び出した場合に発生する可能性があります (したがって、失敗するはずです)。
どう思いますか?すべて問題ないように思える場合、何かが失敗したときに WCF を介してユーザーに適切に通知するにはどうすればよいでしょうか? 、ArgumentException
、InvalidOperationException
またはエラーのリストを含む例外 (CustomerValidator クラスを使用して顧客オブジェクトを検証した後、ApplicationService によってスローされます)。どうにかしてこれらすべての例外をキャッチし、それらを WCF によってスローされる一般的なエラー例外に変換して、クライアントがそれに反応し、何が起こったかをユーザーに通知できるようにする必要がありますか?
私たちのアプローチについてあなたの考えを聞きたいです。私たちはこのかなり大きなアプリケーションを構築し始めたばかりで、検証を実行する良い方法を見つけたいと思っています。私たちのアプリケーションには、データの正確性が非常に重要な非常に重要な部分がいくつかあるため、検証が重要です!