2012-11-02 33 views
2

我在我的asp.net web api的模型类上实现了IValidatableObject。某些对象需要访问数据存储库才能执行完整验证。是否有可能注入到asp.net web api模型类

如何在调用IValidatableObject.Validate之前解决DAL依赖关系 - 还是有其他方法可以解决Validate调用中的依赖关系吗?

请注意,我试图使用autofac,根据Inject into asp.net web api model with autofac,但它看起来像模型没有使用依赖解析器调用。

+1

在我看来,你会对这个感兴趣:http://aspnetwebstack.codeplex.com/workitem/463我真的需要这个特性来实现。如果你愿意,你也可以为此投票。 – tugberk

回答

5

您的模型类不应该是依赖注入的一部分。他们也不应该为他们自己的验证负责(尽管用验证属性来装饰它们 - 这仅仅是元数据 - 将是很好的)。

而是定义一个适当的抽象来进行验证。例如,定义了这个抽象:

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

这样你就可以拥有的IValidator<T>接口特定类型的零个,一个或多个实现,并且可以与Autofac都非常有效注册此。

当一个类型没有验证,就可以让容器传回一个默认的空白 - 实现:

// 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允许您为您注册装饰器。

+0

感谢您的详细解答 - 我将为它的有用内容加注,但我有理由希望将验证逻辑从最初实现的位置(在POST和PUT方法的顶部)移动到模型类,I我还没准备好放弃IValidatableObject的便利,因为我希望在一个地方为特定的类(包括声明为属性的那些类和那些需要更详细的编码的类)制定所有规则。 – dice

+0

@Steven - 谢谢你的回答。它是否也与Unity一起工作?任何提示如何为这种情况设置Unity?特别是Unity如何创建一个CompositeValidator实例,其中所有相关的IEnumerable都是>? – Tohid

+1

@Tohid:对不起。我对Unity没有经验。尝试在SO上发布一个新问题。祝你好运 – Steven

相关问题