是否可以注入asp.net web api模型类

dic*_*ice 2 c# dependencies dependency-injection asp.net-web-api

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

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

请注意,我正在尝试使用autofac,根据使用autofac 注入到asp.net web api模型中,但它看起来像我没有使用依赖项解析器调用模型.

Ste*_*ven 5

模型类不应该是依赖注入的一部分.他们也不应该对自己的验证负责(尽管用验证属性装饰它们 - 这只是元数据 - 会没问题).

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

public interface IValidator<T>
{
    ValidationResult Validate(T instance);
}
Run Code Online (Sandbox Code Playgroud)

这样,您可以IValidator<T>为特定类型设置接口的零个,一个或多个实现,并且您可以使用Autofac非常有效地注册这一点.

当类型没有验证时,您可以让容器传回默认的-empty-实现:

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

当一个类型定义了多个验证器时,您可以将它们包装在一个复合中:

// 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

而不是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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Autofac允许您为您注册装饰器.