2016-04-30 6 views
2

FluentValidationバリデータがSimple Injectorで動作するのにはいくつか問題があります。FluentValidation Validatorsとバリデーターが配列として注入されるシンプルインジェクタ

public CommandHandlerValidationDecorator(
    IRequestHandler<TRequest, TRepsonse> innerHandler, 
    IValidator<TRequest>[] validators) 
{ 
    _decoratedHandler = innerHandler; 
    _validators = validators; 
} 

問題は第二のパラメータ、IValidator<TRequest>[] validatorsである:

は私がのコンストラクタでデコレータを持っています。私はなっていたエラーメッセージに導かれ

次のように、私は私の設定をした:

container.Register(typeof(FluentValidation.IValidator<>), new[] { assembly }); 
container.RegisterCollection(typeof(FluentValidation.IValidator<>), new[] { assembly }); 
container.Register(typeof(IRequestHandler<,>),new [] { assembly }); 
container.RegisterDecorator(typeof(IRequestHandler<,>), 
    typeof(CommandHandlerValidationDecorator<,>)); 

これは私がウェブあたりの要求に寿命のスコープを変更アップまで、うまく働いた:

container.Register(typeof(FluentValidation.IValidator<>), new[] { assembly }, 
    Lifestyle.Scoped); 
container.RegisterCollection(typeof(FluentValidation.IValidator<>), new[] { assembly }); 
container.Register(typeof(IRequestHandler<,>),new [] { assembly }, Lifestyle.Scoped); 
container.RegisterDecorator(typeof(IRequestHandler<,>), 
    typeof(CommandHandlerValidationDecorator<,>), Lifestyle.Scoped); 

RegisterCollectionをWebリクエストごとにスコープできないように見えますが、ライフスタイルの不一致により例外がスローされるため、問題になります:

追加情報:ライフスタイルの不一致が発生しました。 CommandHandlerValidationDecorator(Web Request)はIValidator [](Transient)に依存します。ライフスタイルの不一致は、アプリケーションの並行性のバグを引き起こす可能性があります。この問題とそれを解決する方法については、https://simpleinjector.org/dialmを参照してください。

おそらく私は悪い練習であることを強制しようとしていますか?ドキュメントのhereに記載されているあなたが見ている

+1

コンストラクタの引数を 'Enumable >'に変更しても問題ありません。 – Steven

+0

@スティーブンスピーディで結果の高い回答をありがとう! – onefootswill

答えて

2

シンプルなインジェクターを注入IEnumerable<T>ICollection<T>IList<T>IReadOnlyCollection<T>IReadOnlyList<T>インスタンスから返されるインスタンスのライフスタイルを維持します。実際には、注入されたものがインスタンスの集合として表示されるべきではありません。IEnumerable<T>それをインスタンスのストリームと考えるべきです。 Simple Injectorは常に同じストリームへの参照を挿入します(IEnumerable<T>またはICollection<T>自体はシングルトンです)。IEnumerable<T>を反復するたびに、コンテナはそのコンポーネントのライフスタイルに基づいてインスタンスを解決するよう求められます。

警告:コレクションの抽象化とは対照的に、配列は一時的なものとして登録されます。配列は可変型です。コンシューマは配列の内容を変更することができます。配列を共有することによって(配列をシングルトンにする)、配列の変更のために関連のないアプリケーションの部分が失敗する可能性があります。配列は具体的な型であるため、ストリームとして機能することができず、配列内の要素は消費コンポーネントの存続期間を取得します。これは、配列が一時的なものとして登録されていないときにlifestyle mismatchesを引き起こす可能性があります。

だから、二つの選択肢持っている:

  1. は、アレイからIEnumerable<T>ICollection<T>IList<T>IReadOnlyCollection<T>またはIReadOnlyList<T>にパラメータの引数を一過性だけでなく、アレイの消費者を作る、または
  2. 変更。
+0

Stevenに感謝します。私はドコモを読んでいる。私はその点を逃した。ここでそれを説明してくれてありがとう。それも良いドキュメントです。 – onefootswill

関連する問題