I am trying to learn how to add custom business rules. I am using CSLA 3.8 and I understand the basics from the book about adding a business rule like the common rules.
I have an object that has FlightTime (decimal) property. This object has 2 other properties whose sum cannot exceed FlightTime, but can equal it.
I have used the Commonrules.MaxValue(of T) as my basis to try to create a new rule. It isn't working. The two property names I'm passing in keep calculating to 0D, but if I do it as one parameter, then it works fine.
Basically, has anyone written a similar business rule that compares several properties of an object to itself? I'd like to see how you do it or maybe someone can see my mistake.
Any help would be fantastic!!!!
Mike
Normal 0 false false false EN-US X-NONE X-NONE
' PIC can't be more then FlightTime; it can be equal
ValidationRules.AddRule(AddressOf MaxValueAgainstSelf(Of
Decimal), New MaxValueAgainstSelfRuleArgs(Of
Decimal)(_flightTimeProperty, "PilotInCommandTime"), 1)
' SIC can't be more then FlightTime; it can be equal
ValidationRules.AddRule(AddressOf MaxValueAgainstSelf(Of
Decimal), New MaxValueAgainstSelfRuleArgs(Of
Decimal)(_flightTimeProperty, "SecondInCommandTime"), 1)
' PIC + SIC can't be more then FlightTime; it can be equal
Dim sumPropertyNames As New List(Of String)
sumPropertyNames.Add("PilotInCommandTime")
sumPropertyNames.Add("SecondInCommandTime")
ValidationRules.AddRule(AddressOf MaxValueAgainstSelf(Of
Decimal), New MaxValueAgainstSelfRuleArgs(Of
Decimal)(_flightTimeProperty, sumPropertyNames), 2)
Public Shared Function MaxValueAgainstSelf(Of T As IComparable)(ByVal
target As Object, ByVal e As RuleArgs) As Boolean
Dim str2 As String
Dim args As DecoratedRuleArgs = DirectCast(e, DecoratedRuleArgs)
Dim businessObjectProperty As T =
DirectCast(target.GetType.GetProperty(e.PropertyName).GetValue(target,
Nothing), T)
Dim compareValue As Decimal = 0D
Dim propertyNames As List(Of String) =
CType(args.Item("propertyNamesOfSameObjectHoldingMaxValue"), List(Of
String))
If propertyNames.Count = 1 Then
compareValue = DirectCast(CallByName(target,
propertyNames(0), Microsoft.VisualBasic.CallType.Get, Nothing),
Decimal)
Else
Dim PropertyValue As Decimal
For Each propertyName As String In propertyNames
PropertyValue = DirectCast(CallByName(target,
propertyName, Microsoft.VisualBasic.CallType.Get, Nothing), Decimal)
compareValue = compareValue + PropertyValue
'compareValue = compareValue +
DirectCast(CallByName(target, propertyName,
Microsoft.VisualBasic.CallType.Get, Nothing), Decimal)
Next
End If
If (businessObjectProperty.CompareTo(compareValue) < 1) Then
Return True
End If
Dim str As String = CStr(args.Item("Format"))
If String.IsNullOrEmpty(str) Then
str2 = compareValue.ToString
Else
str2 = String.Format(String.Format("{{0:{0}}}", str),
compareValue)
End If
e.Description = String.Format("{0} may not exceed {1}",
RuleArgs.GetPropertyName(e), compareValue)
Return False
End Function
Public Class MaxValueAgainstSelfRuleArgs(Of T)
Inherits DecoratedRuleArgs
' Methods
Public Sub New(ByVal propertyInfo As IPropertyInfo, ByVal
propertyNameOfSameObjectHoldingMaxValue As String)
MyBase.New(propertyInfo)
Dim names As New List(Of String)
names.Add(propertyNameOfSameObjectHoldingMaxValue)
MyBase.Item("propertyNamesOfSameObjectHoldingMaxValue") = names
MyBase.Item("Format") = String.Empty
MyBase.Item("ValueType") = GetType(T).FullName
End Sub
Public Sub New(ByVal propertyInfo As IPropertyInfo, ByVal
propertyNamesOfSameObjectHoldingMaxValue As List(Of String))
MyBase.New(propertyInfo)
MyBase.Item("propertyNamesOfSameObjectHoldingMaxValue") =
propertyNamesOfSameObjectHoldingMaxValue
MyBase.Item("Format") = String.Empty
MyBase.Item("ValueType") = GetType(T).FullName
End Sub
Public ReadOnly Property
PropertyNamesOfSameObjectHoldingMaxValue() As List(Of String)
Get
Return
DirectCast(MyBase.Item("propertyNamesOfSameObjectHoldingMaxValue"),
List(Of String))
End Get
End Property
End Class
Copyright (c) Marimer LLC