dependency-injectionunity-containerenterprise-libraryvalidation-application-bl

Inject values into custom VAB validator


I'm building a mvc webapp that shares model objects with an existing winforms app. I'm introducing VAB validation into it. One of the items I need to validate is an int that can be one of x levels.

I've written a LevelValidator, but it needs to have the levels accessible.

Regarding the new call in this code, it looks like I should inject the LevelValidator instead of Levels? Other ways?

public class LevelValidatorAttribute : ValueValidatorAttribute
{
    protected override Microsoft.Practices.EnterpriseLibrary.Validation.Validator DoCreateValidator(Type targetType)
    {
        LevelValidator validator = new LevelValidator();
        validator.Levels = this.Levels;
        return validator;
    }

    [Dependency]
    public Levels Levels { get; set; }
}

Solution

  • You can't use dependency injection on attributes, because attributes are not controlled and created by a dependency injection framework, but controlled by the CLR itself. Try having a design were your attribute does not need dependency injection.

    If all fails, you can use the Service Locator pattern inside the LevelValidator (best to leave the attribute allone) and make a call to the unity container from within the LevelValidator class. For this to work, you need to have a static field that holds the container. For instance:

    public class LevelValidator : Validator
    {
        public static UnityContainer Container { get; set; }
    
        public LevelValidator()
        {
            this.Levels = Container.Resolve<Levels>();
        }
    
        public Levels Levels { get; set; }
    }
    

    In the startup path of your application you need to set this static Container property, as follows:

    public void Main()
    {
        var container = new UnityContainer();
    
        // configure it
    
        LevelValidator.Container = container;
    }
    

    This solution is far from ideal and should be prevented in most cases. However, the creation of the attribute and the LevelValidator is outside the control of Unity.