VAB retrieve properties from Attribute based validation

Topics: Validation Application Block
May 25, 2007 at 7:59 PM
We are currently trying to create Unit Test classes for our classes that use VAB on several properties to automate the testing for the entire class. Meaning that we would like a test class that through code will identify the VAB attributes that have been set, identify the rule, and force the rule to fail.

The issue we're having is that we are able to identify all VAB attributes that have been applied to each attribute, but when locating the StringLengthValidatorAttribute I cannot programatically retrieve the upper/lower bound info (size and bound type (in/exclusive) that was set on the property. These values show up in the watch window as non-public (hidden),

My question is once we have identified the StringLengthValidatorAttribute being attached to a property is there a way to identify the lower/upper bound values that were set on the property?

TIA,
TJ
May 26, 2007 at 7:08 PM
I recommend looking at the Unit Tests that ship with Enterprise Library. The P&P Team has tests for each one of the validators so looking at their tests may help you with your own.

Regards,

Dave

______________________________

David Hayden
Microsoft MVP C#
May 28, 2007 at 5:05 PM
Edited May 28, 2007 at 7:55 PM
Thanks for the response and pointing me in the direction of some sample unit tests. I am having trouble with one thing that I'm hoping you can shed some light on.

In both of the UnitTest projects, (VSTS and Nunit), there is a TestMethod with the name: AttributeWithLowerAndUpperBoundsOnlyCreatesAppropriateValidator.

Each of these tests creates a StringLengthValidatorAttribute:
ValidatorAttribute attribute = new StringLengthValidatorAttribute(10, 20);

The next line creates a validator object based on the settings defined in the Attribute:
Validator validator = ((IValidatorDescriptor)attribute).CreateValidator(null, null, null);

The final step prior to being able to access the properties of the StringLengthValidator is:
StringLengthValidator stringLengthValidator = validator as StringLengthValidator;

The following is what I have completed in my UnitTest class. The concept of my Unit Test is to loop through all properties defined in my Entity class, and then through the Attributes defined for each property.

Sample:

foreach (PropertyInfo myInfo in myType.GetProperties())
{
foreach (Attribute attribute in myInfo.GetCustomAttributes(true))
{ if (attribute is MSValidation.Validators.StringLengthValidatorAttribute)
{
Validator validator = ((IValidatorDescriptor)(ValidatorAttribute)attribute).CreateValidator(null, null, null);
Assert.IsNotNull(validator);

StringLengthValidator stringLengthValidator = validator as StringLengthValidator;
Assert.IsNotNull(stringLengthValidator);
}
}
}

The issue is that I am getting a compile error of:

Microsoft.Practices.EnterpriseLibrary.Validation.IValidatorDescriptor' is inaccessible due to its protection level
D:\Development\UnitTest\Entity\CustomerUnitTest.cs

As expected, the IValidatorDescriptor is not color-coded in my unit test but is in the sample UnitTests. My project is referencing the EntLib...Validation DLL but I am obviously missing something. Can you help?

I was looking into the InternalsVisibleTo attribute that can be applied at the Assembly level, but I don't know if this can be used in this case as I believe the value has to be applied in the Source DLL before compilation. Should I keep looking at the InternalsVisibleTo attribute?

Thanks,
TJ
May 28, 2007 at 8:42 PM
Update...I managed to get this working.

I opened the actual VAB c# project ("D:\EntLib3Src\App Blocks\Src\Validation\Validation.csproj") and modified the AssemblyInfo.cs file within this project to include the line:

assembly: InternalsVisibleTo("SourceApplication.UnitTest")

The SourceApplication.UnitTest is the namespace of my unit testing project.

After re-compiling the application, I have taken the updated "Microsoft.Practices.EnterpriseLibrary.Validation.dll" file and then updated the reference to this DLL in my application. Presto! the IValidatorDescriptor is now accessible and can convert the attribute into a valid Validator.

Thanks for the help.
TJ