6

I have found several questions on this subject, but have not found a clean and simple solution.

This is what I'm doing (using Autofac 3.3.0) for registering

builder.RegisterType<MerchantRepo>().As<IMerchantRepo>().PropertiesAutowired();

This is my validation class

public class MerchantMustBeUniqueAttribute : ValidationAttribute
{
    public IMerchantRepo MerchantRepo { get; set; }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        int merchantId = Convert.ToInt32(value);

        if (MerchantRepo.Exists(merchantId))
        {
            return new ValidationResult(ErrorMessage);
        }
        else
        {
            return ValidationResult.Success;
        }
    }
}

My merchant repo is always null.

Edit:

This is part of my view model

public class MerchantCreationModel
{
    [Required]
    [MerchantMustBeUnique(ErrorMessage = "Already exists!")]
    public int? NewMerchantId { get; set; }
}

Autofac registration

public static void RegisterDependencies()
{
    var builder = new ContainerBuilder();

    builder.RegisterFilterProvider(); // Inject properties into filter attributes
    builder.RegisterControllers(typeof(MvcApplication).Assembly);

    builder.RegisterType<MerchantRepo>().As<IMerchantRepo>().PropertiesAutowired();

    IContainer container = builder.Build();
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
ThunderDev
  • 1,118
  • 2
  • 19
  • 38
  • Can you show how you've applied the validation attribute and show the other registrations, like where you register the Autofac filter provider? – Travis Illig Sep 24 '14 at 16:06
  • @TravisIllig This is a `ValidationAttribute`; unless I'm missing something big after a thorough search, Autofac doesnt do anything specific to provision those .... am I? – Ruben Bartelink Feb 04 '16 at 18:10
  • Yes you are correct, it only works on action filters – ThunderDev Feb 04 '16 at 18:19

2 Answers2

3

I solved my problem using the DependencyResolver class in ASP.NET MVC.

IMerchantRepo repo = DependencyResolver.Current.GetService<IMerchantRepo>();
ThunderDev
  • 1,118
  • 2
  • 19
  • 38
1

I solved it in a way that doesn't end up littering the code with with Serice Location 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