使用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