-1

I have the following validation attribute class:

public class ZipCodeValidationAttribute : ValidationAttribute
{
    private readonly IValidationRepository _repository;

    public override bool IsValid(object value)
    {
        var repository = _repository;

        return repository.IsPostalCodeValid((string) value);

    }
}

To test I am trying to use Autofac as my IOC and use property injection. I've set up the test as follows:

 [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);
 }

During the test my repository isn't being resolved. New to Autofac and hoping someone can point me in the right direction.

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
mservais
  • 570
  • 1
  • 7
  • 20

2 Answers2

0

I solved the whole problem (triggering DI under the control of Validator.TryValidate etc / ASP.NET MVC etc) in this answer, enabling one to write:

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);
    }
}

With some helper classes (look over there), you wire it up e.g. in ASP.NET MVC like so in the Global.asax :-

DataAnnotationsModelValidatorProvider.RegisterAdapterFactory(
    typeof(ValidatorServiceAttribute),
    (metadata, context, attribute) =>
        new DataAnnotationsModelValidatorEx(metadata, context, attribute, true));
Community
  • 1
  • 1
Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
-1

You need to declare the repository as a property to be auto wired by Autofac.

public class ZipCodeValidationAttribute : ValidationAttribute
{
    public IValidationRepository Repository { get; set; }

    public override bool IsValid(object value)
    {
        return Repository .IsPostalCodeValid((string) value);
    }
}
mservais
  • 570
  • 1
  • 7
  • 20
Eranga
  • 32,181
  • 5
  • 97
  • 96
  • 1
    Still was giving me grief. Repository is still null and not being resolved because the property was private. Once I made it public, everything aligned. Grazi! – mservais Sep 20 '12 at 11:46
  • i'm having same issue... http://stackoverflow.com/questions/15879967/autofac-property-injection-with-validationattribute – Alex Apr 08 '13 at 14:25
  • @mservais you need to un-accept this as it is misleading. Autofac does not have a way to inject into actual `ValidationAttribute`s borne by models taking part in model binding – Ruben Bartelink Feb 04 '16 at 18:15
  • @Eranga While this answer is only answering the question and is answerin it correctly, the problem with the for me that IRL the instantiation is not done by Autofac. Hence while we have a solution for making the test pass, the victory is moot. For me, your answer should either be [Mu](https://en.wikipedia.org/wiki/Mu_(negative)#.22Unasking.22_the_question) or at a minimum point that out – Ruben Bartelink Feb 04 '16 at 18:21