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

C# 是否可以注入asp.net web api模型类,c#,asp.net-web-api,dependency-injection,dependencies,C#,Asp.net Web Api,Dependency Injection,Dependencies,我正在asp.net web api中的模型类上实现IValidatableObject。某些对象需要访问数据存储库才能执行完全验证 如何在调用IValidatableObject.Validate之前解析DAL依赖关系?或者是否有其他方法来解析Validate调用中的依赖关系 请注意,我正在尝试使用autofac,如,但在我看来,该模型不是使用依赖项解析器调用的。您的模型类不应该是依赖项注入的一部分。他们也不应该对自己的验证负责(尽管用验证属性(仅仅是元数据)装饰它们也可以) 相反,定义一个适

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

如何在调用IValidatableObject.Validate之前解析DAL依赖关系?或者是否有其他方法来解析Validate调用中的依赖关系


请注意,我正在尝试使用autofac,如,但在我看来,该模型不是使用依赖项解析器调用的。

您的模型类不应该是依赖项注入的一部分。他们也不应该对自己的验证负责(尽管用验证属性(仅仅是元数据)装饰它们也可以)

相反,定义一个适当的抽象来进行验证。例如,定义此抽象:

public interface IValidator<T>
{
    ValidationResult Validate(T instance);
}
公共接口IValidator
{
验证结果验证(T实例);
}
通过这种方式,您可以为特定类型的
IValidator
接口提供零个、一个或多个实现,并且您可以在Autofac中非常有效地注册这些实现

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

// Implementation of the Null Object pattern
public class EmptyValidator<T> : IValidator<T>
{
    public ValidationResult Validate(T instance)
    {
        return ValidationResult.ValidResult;
    }
}
//空对象模式的实现
公共类EmptyValidator:IValidator
{
公共验证结果验证(T实例)
{
返回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;
    }
}
//复合模式的实现
公共类复合Evalidator:IValidator
{
私有只读IEnumerable列;
公共复合Evalidator(IEnumerable col)
{
this.col=col;
}
公共验证结果验证(T实例)
{
ValidationResult总计=ValidationResult.ValidResult;
foreach(此.col中的var验证器)
{
var result=validator.Validate(实例);
总计=ValidationResult.Append(总计,结果);
}
返回总数;
}
}
不要将
IValidator
直接注入Web API控制器,而是创建一个围绕
IRepository
接口的装饰器。通过这种方式,您可以添加验证行为,而无需更改存储库。此类实现可能如下所示:

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);
    }
}
公共类ValidationRepositoryDecorator
:i假定的
{
私人只读存储库;
专用只读IValidator验证器;
公共验证RepositoryDecorator(
我相信你,
IValidator验证器)
{
这是装饰过的;
this.validator=验证程序;
}
公共void保存(T实例)
{
var result=this.validator.Validate(实例);
如果(!results.IsValid)
新的ValidationException(结果);
this.decordent.Save(实例);
}
}

Autofac允许您注册decorators。

感谢您提供的详细答案-我将对它的有用内容进行更新投票,但是我有理由希望将验证逻辑从最初实现的位置(在POST和PUT方法的顶部)移动到模型类,我还没有准备好放弃IValidatableObject的便利性,因为我希望某个特定类的所有规则(包括声明为属性的规则和需要更精细编码的规则)都放在一个地方。@Steven-谢谢你的回答。它也与团结一起工作吗?有没有关于如何为这个场景设置Unity的提示?特别是Unity如何使用所有相关的IEnumerable创建CompositeValidator实例?@Tohid:对不起。我对团结没有什么经验。试着在这里发布一个新问题。好luckit在我看来,你会对这个感兴趣:我真的需要实现这个特性。如果你愿意,你也可以投赞成票。