Creating Generic Rules

Creating Generic Rules

Old forum URL: forums.lhotka.net/forums/t/6753.aspx


BuckeyeJeff posted on Tuesday, April 07, 2009

I am wanting to create a reusable rule that will accept more than one property and run a rule on it.  For example, we have several objects that need to check that one date is less than the other.   But, the two dates are not the same property names.  How can you make a general reusable rule that can accept two dates of any name and apply validation to them.

RockfordLhotka replied on Tuesday, April 07, 2009

You'll need to create your own custom RuleArgs subclass to contain the second property name. The primary property name is already carried through automatically.

MarkD replied on Wednesday, April 15, 2009

Here is one we wrote.

Functions:

Public Function LessThan(Of T As IComparable)(ByVal target As Object, ByVal e As RuleArgs) As Boolean
            Dim pRuleArgs As DecoratedRuleArgs = DirectCast(e, DecoratedRuleArgs)
            Dim pPropertyMain As PropertyInfo = target.GetType.GetProperty(e.PropertyName)
            Dim pPropertyToCompare As PropertyInfo = target.GetType.GetProperty(DirectCast(e, LessThanRuleArgs(Of T)).LessThanProperty)
            Dim pMainValue As T = CType(pPropertyMain.GetValue(target, Nothing), T)
            Dim pCompareValue As T = CType(pPropertyToCompare.GetValue(target, Nothing), T)

            If pMainValue.CompareTo(pCompareValue) < 0 Then
                Return True
            Else
                e.Description = String.Format("{0} must be less than {1}.", RuleArgs.GetPropertyName(e), DirectCast(e, LessThanRuleArgs(Of T)).LessThanFriendlyName)
                Return False
End If


        End Function



        Public Class LessThanRuleArgs(Of T)
            Inherits Csla.Validation.DecoratedRuleArgs

            Public Sub New(ByVal propertyName As String, ByVal friendlyName As String, ByVal severity As Csla.Validation.RuleSeverity, ByVal lessThanProperty As String, ByVal lessThanFriendlyName As String)
                MyBase.New(propertyName, friendlyName, severity)
                Me("LessThanProperty") = lessThanProperty
                Me("LessThanFriendlyName") = lessThanFriendlyName
            End Sub

            Public ReadOnly Property LessThanProperty() As String
                Get
                    Return DirectCast(Me("LessThanProperty"), String)
                End Get
            End Property

            Public ReadOnly Property LessThanFriendlyName() As String
                Get
                    Return DirectCast(Me("LessThanFriendlyName"), String)
                End Get
            End Property

        End Class


Usage:

ValidationRules.AddRule(AddressOf LessThanOrEqual(Of Decimal), New LessThanRuleArgs(Of Decimal)("MeasureOrdered", "Ordered", Csla.Validation.RuleSeverity.Error, "Available", "Available"), 1)


Copyright (c) Marimer LLC