Ответ 1
Вариант 1 не подходит. Единственный способ, которым это будет работать, - это затянуть зависимость с помощью анти-шаблона локатора сервиса.
Вариант 2 не работает.. Хотя я не мог понять, как это возможно из-за требований атрибутов С#, это возможно. См. Следующие ссылки:
- Разрешение контейнеров IoC для атрибутов проверки в ASP.NET MVC
- NInjectDataAnnotationsModelValidatorProvider
Вариант 3: Я не знал об этом раньше, но то, что кажется очень мощным способом написания валидаторов, заключается в использовании ModelValidator и соответствующий ModelValidatorProvider.
Сначала вы создаете свой собственный ModelValidatorProvider:
public class CustomModelValidatorProvider : ModelValidatorProvider
{
public CustomModelValidatorProvider(/* Your dependencies */) {}
public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
{
if (metadata.ModelType == typeof(YourModel))
{
yield return new YourModelValidator(...);
}
}
}
ASP.NET MVC IDependencyResolver будет пытаться разрешить вышеупомянутый провайдер, поэтому, пока он зарегистрирован в вашем контейнере IoC, вы выиграли ' нужно делать что-нибудь еще. И затем ModelValidator:
public class EntryRatingViewModelValidatorMvcAdapter : ModelValidator
{
public EntryRatingViewModelValidatorMvcAdapter(
ModelMetadata argMetadata,
ControllerContext argContext)
: base(argMetadata, argContext)
{
_validator = validator;
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
if (/* error condition */)
{
yield return new ModelValidationResult
{
MemberName = "Model.Member",
Message = "Rating is required."
};
}
}
}
Как поставщик получает через IDependencyResolver
, и поставщик имеет полный контроль над возвращенным ModelValidator
, я легко мог вставлять зависимости и выполнять необходимую проверку.