使用ASP.NET MVC,是否可以使用带有数据注释属性的构造函数注入(具体而言,我使用的是验证属性)?数据注解构造函数注入
我想做些什么可以做的是:
public class NoEmailTakenAttribute : ValidationAttribute
{
public NoEmailTakenAttribute(IService service) { .. }
}
这可能吗?
谢谢。
使用ASP.NET MVC,是否可以使用带有数据注释属性的构造函数注入(具体而言,我使用的是验证属性)?数据注解构造函数注入
我想做些什么可以做的是:
public class NoEmailTakenAttribute : ValidationAttribute
{
public NoEmailTakenAttribute(IService service) { .. }
}
这可能吗?
谢谢。
你不能使用我看到使用反射器的控制器注入,但它似乎可以使用属性注入。通过创建一个继承自DataAnnotationsModelValidatorProvider
的类,并通过重写方法GetValidators
,在验证发生之前,属性可以被注入属性似乎是合理的......这是从初始分析开始,尚未完全确定。
您可以通过创建基础控制器类并为IService接口声明属性并使用参数IService编写基础控制器类来完成此操作。在你的派生类中使用它。 由于asp.net mvc使用默认的控制器构造函数来初始化那个时候你的服务被派生类的参数化构造函数实例化。
你在说控制器注入;我在谈论数据注释属性注入。 –
我不认为有一个简单的方法来做自定义数据注释的构造函数注入甚至属性注入。 @BrianMains的建议听起来似乎是合理的,但我自己并没有走得太远。
解决复杂性的一种方法是在自定义数据注释中使用服务定位器来获取所需的任何依赖关系。不是很干净,但会得到相同的结果。
检查这个环节出更多的信息:Dependency injection in custom DataAnnotations in ASP.Net MVC 3
由Brian电源提出的解决方案应该能正常运行。我不认为构造函数注入在这里是一种选择,但是注入属性可以完成这项工作。您可以从ModelValidatorProvider
派生和你的实现可能看起来类同此:
public class MyModelValidatorProvider : ModelValidatorProvider
{
private IDiContainer _container;
public MyModelValidatorProvider(IDiContainer container)
{
_container = container;
}
public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
{
List<ModelValidator> validators = new List<ModelValidator>();
PropertyInfo targetProperty = metadata.ContainerType.GetProperty(metadata.PropertyName);
if (targetProperty.GetCustomAttributes(false).Any(attr => attr.GetType() == typeof(NoEmailTakenAttribute)))
{
DataAnnotationsModelValidator<NoEmailTakenAttribute> validator = new DataAnnotationsModelValidator<NoEmailTakenAttribute>(
metadata, context, _container.Resolve<NoEmailTakenAttribute>());
validators.Add(validator);
}
return validators;
}
}
我没仔细看到ModelMetadata
,只是用来refelction来决定是否返回验证或没有,但它可能可以做的更好。
然后在Global.asax
添加以下内容:
ModelValidatorProviders.Providers.Add(new MyModelValidatorProvider(InstanceOfContainer));
,你应该是好去。这里唯一的问题是您的验证器也会由默认机制创建。显然这会导致你的验证器没有注入适当的依赖关系。我不知道如何从默认创建中排除验证器,但是如果您在验证器中正确地检查空值,它应该可以正常工作(我必须说一些解决方法,但也许您会找到更好的方法)。
你想达到什么目的? – Jeroen
使用DI功能创建验证属性,就像您可以使用DI创建控制器一样。 –
我应该知道DI是什么意思? – Jeroen