3

私のビジネスレイヤーには、IValidatableObjectを実装するオブジェクトがあります。これらのエンティティのビジネスルールを外部アセンブリに入れてから、次のタイプのバリデーターを呼び出します。

public IEnumerable<ValidationResult> Validate(ValidationContext vc){}

DIを使用して、IValidatableObjectインターフェイスを実装するタイプのコンストラクターにバリデーターを挿入しました。

   public Customer(ICustomerValidator validator)
        {
            this.Validator = validator;
        }

タイプファクトリのUnityに呼び出して、そこから注入すると思いました。

しかし、多くの場合、エンティティは変更されずに読み取られます。つまり、顧客エンティティです。ユースケースをサポートするためだけに存在し、実際には変更されない可能性があるため、必ずしもバリデーターは必要ありません。

だから私は次のいずれかができると思います:

  1. CustomerEditクラスを作成してから、CustomerReadクラスではなく、それらのクラスにのみコンストラクタインジェクターを使用しますが、これにより、このアプリケーションには本当に必要のないクラスの爆発的な増加につながります。
  2. 単一の顧客クラスを用意し、必要に応じてバリデーターを挿入します。

上記の2の場合、IValidatableObjectインターフェイスの実装のValidateメソッドが適切な場所のようです。問題は、多くの場合、このメソッドが自分以外のコードによって呼び出されることです。たとえば、Entity Frameworkから、および一部のタイプでは、モデルクラスとして使用されるMVCから。

これで、DIできるように、フレームワークコードのメソッドをオーバーライドする必要があります。これは正しく「見えない」のですが、正直なところ、理由はわかりません。

次に見たのは、ValidationContextのGetService()メソッドです。

public IEnumerable<ValidationResult> Validate(ValidationContext vc)
{

var customerValidator = (ICustomerValidator)vc.GetService(typeof(ICustomerValidator));
return customerValidator.Validate();

}

しかし、これを始めたら、ServiceLocatorアンチパターンの領域全体に足を踏み入れて、デメテルの法則を破り、テストを完全に苦痛にしたのではないでしょうか。

それで、これからよりクリーンな方法がありますか、それとも私が概説したものから私のトレードオフを選択するだけの問題ですか?

4

2 に答える 2

2

最も重要な原則:KISS

したがって、10000のビジネス・オブジェクトを作成しているのでない限り、気にせず、常に検証サービスを注入してください。

そうすることでパフォーマンスが低下する場合は、必要に応じてクラスを読み取り/編集モデルに分割します。

于 2013-03-27T08:34:34.273 に答える
1

質問に対するスティーブンスのコメントは、私の質問に関連するいくつかのブログ投稿に私を導きました。

これらのブログ投稿のこの要点は、注入される依存関係が「時々使用される」場合にコンストラクターの注入が過剰に使用されることですが、コンストラクターに依存関係を含めることで、「常に必要」になります。

この記事の場合、説明されている依存関係はOrderShipperですが、私の質問と同じくらい簡単にバリデーターになる可能性があります。

だからそれは

コンストラクターのオーバーインジェクションアンチパターン-JeffreyPalermo

ここで反論されます

反論:MarkSeemannによるコンストラクターの過剰注入アンチパターン

そして、反論はここでさらに洗練されます:

MarkSeemannによるレイジーコンポーネントのDIの有効化

受け入れられた答えはさておき、もし私が本当に自分のデザインを再プッシュしたいのなら、ドメインクラスにバリデーターを注入するなら、代わりにAbstractFactoryを注入することができます。

いつものように、依存関係の存続期間がコンシューマーよりも短い可能性がある場合、解決策は(コンストラクターを介して!)抽象ファクトリを注入することです-Mark Seemann

于 2013-03-28T02:45:29.767 に答える