How to register an extended AttributeValidatorFactory

Topics: Validation Application Block
Oct 8, 2013 at 4:10 PM
I have extended the default AttributeValidatorFactory
public class ExtendedAttributeValidationFactory : AttributeValidatorFactory

with EL 5 i was able to register the extended factory using

Container.RegisterType<AttributeValidatorFactory, ExtendedAttributeValidationFactory>(new ContainerControlledLifetimeManager());

That does not seem to work in EL 6

How do i register ExtendedAttributeValidationFactory in EL 6 so i can use ValidationFactory.CreateValidator(entityType)?

I am trying to do something like this:

//Register my extended AttributeValidatorFactory
_unityContainer.RegisterType<AttributeValidatorFactory, ExtendedAttributeValidationFactory>(new ContainerControlledLifetimeManager());

// Setup the configuration Factory
IConfigurationSource configurationSource = new FileConfigurationSource(UnitTestConfigFile);
var cf = new ConfigurationValidatorFactory(configurationSource);

ValidationFactory.CreateValidator(entityType) still uses the default AttributeValidatorFactory
Oct 9, 2013 at 8:01 AM
It looks like AttributeValidatorFactory can no longer be set. One option would be to modify Enterprise Library to add a SetDefaultAttributeValidatorFactory method.

Another approach might be to piggy back on the SetDefaultConfigurationValidatorFactory method. Basically, make the ExtendedAttributeFactory extend ConfigurationValidatorFactory and have the custom factory manage both.

I'm assuming that you are using the code from or some variant. If not then perhaps it will give some idea:
    public class ExtendedAttributeValidationFactory : ConfigurationValidatorFactory
        private static readonly MemberAccessValidatorBuilderFactory Default = new MemberAccessValidatorBuilderFactory();

        public ExtendedAttributeValidationFactory(IConfigurationSource configSource) : base(configSource)           

        protected override Microsoft.Practices.EnterpriseLibrary.Validation.Validator InnerCreateValidator(
            Type targetType, string ruleset,
            ValidatorFactory mainValidatorFactory)
            Microsoft.Practices.EnterpriseLibrary.Validation.Validator configValidator = null;

            if (ConfigurationSource != null)
                configValidator = base.InnerCreateValidator(targetType, ruleset, mainValidatorFactory);

            var metaDataValidator =
                    targetType, ruleset);

            var validators = GetValidators(configValidator, metaDataValidator);

            if (validators.Count > 1)
                return new AndCompositeValidator(validators.ToArray());

            return validators.First();

        private List<Microsoft.Practices.EnterpriseLibrary.Validation.Validator> GetValidators(
            Microsoft.Practices.EnterpriseLibrary.Validation.Validator configValidator,
            Microsoft.Practices.EnterpriseLibrary.Validation.Validator metadataValidator)
            List<Microsoft.Practices.EnterpriseLibrary.Validation.Validator> validators = new List<Microsoft.Practices.EnterpriseLibrary.Validation.Validator>();

            if (configValidator != null)

            if (metadataValidator != null)

            return validators;

        private Microsoft.Practices.EnterpriseLibrary.Validation.Validator CreateValidatorForMetaDataSelfValidation(
            Type targetType, string ruleset)
            var attributes = GetMetadataTypes(targetType).ToArray();

            if (attributes.Length == 0)
                return null;

            var flags = BindingFlags.Public |
                BindingFlags.NonPublic | BindingFlags.Static;

            var selfValidators = (
                from attribute in attributes
                from method in attribute.MetadataClassType.GetMethods(flags)
                where method.ReturnType == typeof(void)
                let parameters = method.GetParameters()
                where parameters.Length == 2
                where parameters[1].ParameterType == typeof(ValidationResults)
                from methodAtrtibute in
                        typeof(SelfValidationAttribute), false)
                where ruleset.Equals(methodAtrtibute.Ruleset)
                select new MetaDataSelfValidationValidator(method)).ToArray();

            if (selfValidators.Length == 0)
                return null;

            return new AndCompositeValidator(selfValidators);

        private static IEnumerable<MetadataTypeAttribute> GetMetadataTypes(
            Type targetType)
            while (targetType != null)
                var metadata = targetType.GetCustomAttributes(
                    typeof(MetadataTypeAttribute), false)

                if (metadata != null)
                    yield return (MetadataTypeAttribute)metadata;

                targetType = targetType.BaseType;

    public class MetaDataSelfValidationValidator : Microsoft.Practices.EnterpriseLibrary.Validation.Validator
        private readonly MethodInfo methodInfo;

        public MetaDataSelfValidationValidator(MethodInfo methodInfo)
            : base(null, null)
            this.methodInfo = methodInfo;

        public override void DoValidate(object objectToValidate,
            object currentTarget, string key,
            ValidationResults validationResults)
            if (objectToValidate != null)
                    new object[] { objectToValidate, validationResults });

        protected override string DefaultMessageTemplate
            get { return null; }

I haven't done a lot of testing on this but it seems to work with the Metadata tag as well as with a config file. I removed the atrributeFactory since it was causing duplicate error messages but it seems to behave the same as the default Enterprise Library set up. Oh yeah, here is how I set up the factory:
var configSource = ConfigurationSourceFactory.Create();
    new ExtendedAttributeValidationFactory(configSource));

Randy Levy
Enterprise Library support engineer
Support How-to
Marked as answer by Seaducer on 10/23/2013 at 11:07 AM
Oct 23, 2013 at 7:07 PM
That works , thank you.
Oct 23, 2013 at 8:38 PM
By the way... Any chance that the code from the article mentioned above would make it into EL validation block. The fact that you can use a separate meta data class to describe Validation including the self Validation tag is awesome.