2

IPageable というインターフェイスを実装する ServiceStack リクエスト DTO がいくつかあります。このインターフェイスにある 2 つのプロパティを検証できるバリデーターがあります。リクエストの種類ごとに 1 つのバリデーターを持つことになると思いますが、それらすべてでその IPageable 関連の検証ロジックを複製する必要がないようにしています。

public class PageableValidator : AbstractValidator<IPageable>
{
    public PageableValidator()
    {
        RuleFor(req => req.Page)
            .GreaterThanOrEqualTo(1);
        RuleFor(req => req.PageSize)
            .GreaterThanOrEqualTo(1)
            .When(req => req.Page > 1);
    }
}

これについて私が持っていたいくつかのアイデアは次のとおりです。

  1. IPageable を実装するすべてのリクエスト タイプに container.RegisterValidators() を適用させることはできないようですが、それが私の最初の考えでした。

  2. すべてのリクエスト定義に複数の<Validator>属性を指定して、リクエスト固有のバリデータと IPageable バリデータの両方を実行できますか?

  3. バリデータの登録時に、IPageable を実装するすべての型に対して IPageable バリデータを実行するように指定できますか?

  4. PageableValidator からルールを取得し、それらをインクルード/実行するリクエスト固有のバリデーターの基本クラスを作成できますか?

をサブクラス化することで、ある種の作業AbstractValidator<T> where T : IPageableを行うことができますが、アスペクト指向の方法で複数のインターフェイスで検証を実行できるようにしたいと考えています。

4

1 に答える 1

2

あなたの質問に対する答えはわかりませんが、あなたの質問を読んだ後、いくつかの選択肢が思い浮かびました。

この属性については詳しくありません<Validator>が、質問 2 に関しては、ページング検証を実行するFilter 属性を作成できます。これにより、リクエストで多くの属性を使用し、それらの優先度を設定できます。

public class PageableValidator : Attribute, IHasRequestFilter
{
    public void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto)
    {
        if (requestDto is IPageable)
        {
            var validator = new PageableValidator(); //could use IOC for this
            validator.ValidateAndThrow(requestDto as IPageable);
        }

    }

    public IHasRequestFilter Copy()
    {
        return (IHasRequestFilter)this.MemberwiseClone();
    }

    public int Priority { get { return -1; //setting to negative value to run it before any other filters} }
}

もう 1 つのオプションは、ページング検証用の抽象クラスを作成することです。これには、リクエストごとにサブクラスが必要であり、もう少しコードと繰り返しが必要です*。ただし、エラー メッセージの処理方法によっては、コードを移動できます。

public abstract class PagerValidatorBase<T> : AbstractValidator<T>
{
    public bool ValidatePage(IPageable instance, int page)
    {
        if (page >= 1)
            return true;

        return false;
    }

    public bool ValidatePageSize(IPageable instance, int pageSize)
    {
        if (pageSize >= 1 && instance.Page > 1)
            return true;

        return false;
    }
}

public class SomeRequestValidator : PagerValidatorBase<SomeRequest>
{
    public SomeRequestValidator()
    {
        //validation rules for SomeRequest
        RuleFor(req => req.Page).Must(ValidatePage);
        RuleFor(req => req.PageSize).Must(ValidatePageSize);
    }
}
  • IMO、繰り返しによりコードがより明確になり(悪いことではありません)、ロジックが重複していないため問題ありません。
于 2013-05-28T17:03:57.090 に答える