C# 是否可以注入asp.net web api模型类
我正在asp.net web api中的模型类上实现IValidatableObject。某些对象需要访问数据存储库才能执行完全验证 如何在调用IValidatableObject.Validate之前解析DAL依赖关系?或者是否有其他方法来解析Validate调用中的依赖关系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,如,但在我看来,该模型不是使用依赖项解析器调用的。您的模型类不应该是依赖项注入的一部分。他们也不应该对自己的验证负责(尽管用验证属性(仅仅是元数据)装饰它们也可以) 相反,定义一个适
请注意,我正在尝试使用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在我看来,你会对这个感兴趣:我真的需要实现这个特性。如果你愿意,你也可以投赞成票。