Autofac и DI для атрибута проверки
У меня есть следующий класс атрибута проверки:
public class ZipCodeValidationAttribute : ValidationAttribute
{
private readonly IValidationRepository _repository;
public override bool IsValid(object value)
{
var repository = _repository;
return repository.IsPostalCodeValid((string) value);
}
}
Чтобы проверить, я пытаюсь использовать Autofac в качестве своего IOC и использовать инъекцию свойства. Я настроил тест следующим образом:
[TestMethod]
public void When_PostalCodeAttribute_Given_ValidPostalCode_Then_SystemReturnsTrue()
{
// arrange
var value = "53051";
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<ValidationRepository>().As<IValidationRepository>().InstancePerDependency();
containerBuilder.RegisterType<ZipCodeValidationAttribute>().PropertiesAutowired();
var container = containerBuilder.Build();
var attrib = container.Resolve<ZipCodeValidationAttribute>();
// act
var result = attrib.IsValid(value);
// assert
Assert.IsTrue(result);
}
Во время теста мой репозиторий не разрешается. Новичок в Autofac и надеюсь, что кто-то может направить меня в правильном направлении.
2 ответа
Решение
Вы должны объявить repository
как свойство, которое будет автоматически подключено Autofac.
public class ZipCodeValidationAttribute : ValidationAttribute
{
public IValidationRepository Repository { get; set; }
public override bool IsValid(object value)
{
return Repository .IsPostalCodeValid((string) value);
}
}
Я решил всю проблему (запуск DI под контролем Validator.TryValidate
etc / ASP.NET MVC и т.д.) в этом ответе, позволяя написать:
class MyModel
{
...
[Required, StringLength(42)]
[ValidatorService(typeof(MyDiDependentValidator), ErrorMessage = "It's simply unacceptable")]
public string MyProperty { get; set; }
....
}
public class MyDiDependentValidator : Validator<MyModel>
{
readonly IUnitOfWork _iLoveWrappingStuff;
public MyDiDependentValidator(IUnitOfWork iLoveWrappingStuff)
{
_iLoveWrappingStuff = iLoveWrappingStuff;
}
protected override bool IsValid(MyModel instance, object value)
{
var attempted = (string)value;
return _iLoveWrappingStuff.SaysCanHazCheez(instance, attempted);
}
}
С некоторыми вспомогательными классами (посмотрите там), вы подключаете его, например, в ASP.NET MVC, как в Global.asax
:-
DataAnnotationsModelValidatorProvider.RegisterAdapterFactory(
typeof(ValidatorServiceAttribute),
(metadata, context, attribute) =>
new DataAnnotationsModelValidatorEx(metadata, context, attribute, true));