Microsoft Enterprise Library 5.0 |
Validation and Inheritance |
If you use inheritance, you need to know how the validation rules are applied throughout the class hierarchy. Here is an example of a simple hierarchy, where class PreferredCustomer inherits from class Customer. (The validator attributes used in the example, such as CustomerNameValidator refer to custom validators and are not validators included with the Validation Application Block.)
C# | Copy Code |
---|---|
public class Customer { [CustomerNameValidator] public string Name { get { ... } set { ... } } [DiscountValidator] public virtual double Discount { get { ... } set { ... } } } public class PreferredCustomer : Customer { [PreferredDiscountValidator] public override double Discount { get { ... } set { ... } } } |
Visual Basic | Copy Code |
---|---|
Public Class Customer <CustomerNameValidator()> _ Public Property Name(ByVal _name As String) Get ' ... End Get Set(ByVal value) ' ... End Set End Property <DiscountValidator()> _ Public Overridable Property Discount(ByVal _discount As Double) Get ' ... End Get Set(ByVal value) ' ... End Set End Property End Class Public Class PreferredCustomer Inherits Customer <PreferredDiscountValidator()> _ Overrides Public Property Discount(ByVal _discount As Double) Get ' ... End Get Set(ByVal value) ' ... End Set End Property End Class |
In this example, the PreferredCustomer class derives from the Customer class, and it also overrides the Discount property.
There are two rules for how validators work within a class hierarchy:
- If a derived class inherits a member and does not override it, the member's validators from the base class apply to the derived class.
- If a derived class inherits a member but overrides it, the member's attributes from the base class do not apply to the derived class.
In this example, the CustomerNameValidator attribute applies to the PreferredCustomer class, but the DiscountValidator attribute does not. Instead, the PreferredDiscountValidator attribute applies.
If this is not the desired behavior, you can use validators of base classes to check instances of derived classes. The following code example shows how to do this. It assumes that you have resolved an instance of the Validation Application Block ValidatorFactory class and stored it in a variable named valFactory.
C# | Copy Code |
---|---|
Validator<Customer> customerValidator = valFactory.CreateValidator<Customer>(); PreferredCustomer myPreferredCustomer = new PreferredCustomer(); // Set properties of PreferredCustomer here ValidationResults r = customerValidator.Validate(myPreferredCustomer); |
Visual Basic | Copy Code |
---|---|
Dim customerValidator As Validator(Of Customer) = valFactory.CreateValidator(Of Customer)() Dim myPreferredCustomer As PreferredCustomer = New PreferredCustomer() ' Set properties of PreferredCustomer here Dim r As ValidationResults = customerValidator.Validate(myPreferredCustomer) |
This example validates a PreferredCustomer object. However, the validation is based on the attributes of the Customer base class. The validation rules defined on the PreferredCustomer class are not applied.
You can use the CreateValidator(Type) overload of the ValidatorFactory class to create a validator that is specific to a class that you provide at run time.
C# | Copy Code |
---|---|
public ValidationResults CheckObject(object obj) { if (obj != null) { Validator v = valFactory.CreateValidator(obj.GetType()); return v.Validate(obj); } else { return null; } } |
Visual Basic | Copy Code |
---|---|
Public Function ValidationResults(ByVal obj As Object) If Not obj Is Nothing Then Dim v As Validator = valFactory.CreateValidator(obj.GetType()) Return v.Validate(obj) Else Return Nothing End If End Function |
This example creates a validator based on the run time type of the input argument to the CheckObject method.