2

asp.net Web API のモデル クラスに IValidatableObject を実装しています。一部のオブジェクトは、完全な検証を実行するためにデータ リポジトリにアクセスする必要があります。

IValidatableObject.Validate への呼び出しの前に DAL 依存関係を解決するにはどうすればよいですか?または、Validate 呼び出しで依存関係を解決する他の方法がありますか?

autofac を使用して asp.net Web API モデルに注入するに従って、autofac を使用しようとしていますが、依存関係リゾルバーを使用してモデルが呼び出されていないように見えます。

4

1 に答える 1

5

モデルクラスは、依存性注入の一部であってはなりません。また、彼ら自身の検証に責任を持つべきではありません(ただし、検証属性(単なるメタデータ)でそれらを装飾することは問題ありません)。

代わりに、検証を行うための適切な抽象化を定義してください。たとえば、次の抽象化を定義します。

public interface IValidator<T>
{
    ValidationResult Validate(T instance);
}

このようにして、特定のタイプのインターフェースの実装を0、1、または複数持つことがIValidator<T>でき、これをすべてAutofacに非常に効果的に登録できます。

タイプに検証がない場合、コンテナにデフォルトの-empty-実装を戻すことができます。

// Implementation of the Null Object pattern
public class EmptyValidator<T> : IValidator<T>
{
    public ValidationResult Validate(T instance)
    {
        return ValidationResult.ValidResult;
    }
}

タイプに複数のバリデーターが定義されている場合、それらをコンポジットでラップできます。

// Implementation of the Composite pattern
public class CompositeValidator<T> : IValidator<T>
{
    private readonly IEnumerable<Validator<T>> col;

    public CompositeValidator(IEnumerable<Validator<T>> col)
    {
        this.col = col;
    }

    public ValidationResult Validate(T instance)
    {
        ValidationResult total = ValidationResult.ValidResult;

        foreach (var validator in this.col)
        {
            var result = validator.Validate(instance);
            total = ValidationResult.Append(total, result);
        }

        return total;
    }
}

IValidator<T>Web APIコントローラーに直接挿入する代わりに、IRepository<T>インターフェースをラップするデコレーターを作成します。このようにして、リポジトリを変更することなく、検証動作を追加できます。このような実装は次のようになります。

public class ValidationRepositoryDecorator<T>
    : IRepository<T>
{
    private readonly IRepository<T> decorated;
    private readonly IValidator<T> validator;

    public ValidationRepositoryDecorator(
        IRepository<T> decorated,
        IValidator<T> validator)
    {
        this.decorated = decorated;
        this.validator = validator;
    }

    public void Save(T instance)
    {
        var result = this.validator.Validate(instance);

        if (!results.IsValid)
            new ValidationException(result);

        this.decorated.Save(instance);
    }
}

Autofacを使用すると、デコレータを登録できます。

于 2012-11-02T11:50:02.270 に答える