Original value tracking

Original value tracking

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


JoeFallon1 posted on Thursday, July 03, 2008

I think this works to optionally track original values for a BO.

===================================================================

You have to create 2 subclasses of the CSLA classes named PropertyInfo and FieldData.

Something like this:

===================================================================

<Serializable()> _
Public Class MyPropertyInfo(Of T)
Inherits PropertyInfo(Of T)
Private _origValue As T
Private _defaultValue As T

#Region " Constructors "

Public Sub New(ByVal name As String)
  MyBase.New(name)
End Sub

Public Sub New(ByVal name As String, ByVal friendlyName As String)
 
MyBase.New(name, friendlyName)
  _defaultValue = GetDefaultValue()
End Sub

Public Sub New(ByVal name As String, ByVal friendlyName As String, ByVal defaultValue As T)
 
MyBase.New(name, friendlyName, defaultValue)
  _defaultValue = defaultValue
End Sub

Private Function GetDefaultValue() As T
 
Dim result As T
 
If GetType(T).Equals(GetType(String)) Then
   
result = DirectCast(DirectCast(String.Empty, Object), T)
 
ElseIf GetType(T).Equals(GetType(Integer)) OrElse GetType(T).Equals(GetType(Long)) OrElse GetType(T).Equals(GetType(Decimal)) OrElse GetType(T).Equals(GetType(Short)) OrElse GetType(T).Equals(GetType(Byte)) Then
   
result = DirectCast(DirectCast(0, Object), T)
 
Else
   
result = Nothing
 
End If

  Return result
End Function

#End Region

Public Property OrigValue() As T
 
Get
   
Return _origValue
 
End Get

  Set(ByVal value As T)
    _origValue = value
 
End Set
End Property

Public Overrides ReadOnly Property DefaultValue() As T
 
Get
   
Return _defaultValue
 
End Get
End Property

'My only real worry here, is that a subclass will need to detect that it contains a child object and handle that correctly -
'so it still isn't necessarily trivial to write a subclass.
'But then again, your PropertyInfo subclass could make that determination and return a standard FieldData rather than
'a custom FieldData for child objects.

Protected Overrides Function NewFieldData(ByVal name As String) As Core.FieldManager.IFieldData
 
If GetType(IEditableBusinessObject).IsAssignableFrom(Me.Type) OrElse GetType(IEditableCollection).IsAssignableFrom(Me.Type) Then

    Return New FieldData(Of T)(name)
 
Else
   
Return New PNIFieldData(Of T)(name, _origValue)
 
End If
End Function

End Class

===================================================================

<Serializable()> _
Public Class MyFieldData(Of T)
Inherits FieldData(Of T)
Implements IFieldData(Of T)

Private _origValue As T

Public Sub New(ByVal name As String, ByVal origValue As T)
 
MyBase.New(name)
  _origValue = origValue
End Sub

Public ReadOnly Property OrigValue() As T
 
Get
   
Return _origValue
 
End Get
End Property

Public Overrides Property Value() As T
 
Get
   
Return MyBase.Value
 
End Get

  Set(ByVal value As T)
   
MyBase.Value = value 'sets IsDirty = True

    If _origValue IsNot Nothing AndAlso MyBase.Value.Equals(_origValue) Then
     
MarkClean() 'sets IsDirty to False
   
End If
 
End Set
End Property

Public Overrides ReadOnly Property IsDirty() As Boolean
 
Get
   
If _origValue IsNot Nothing AndAlso MyBase.Value.Equals(_origValue) Then
     
Return False
   
Else
     
Return MyBase.IsDirty
   
End If
 
End Get
End Property

End Class

===================================================================

Then in your BO you declare the managed property like this:
Private Shared AcctdescProperty As MyPropertyInfo(Of String) = CType(RegisterProperty(Of String)(GetType(Acct), New PNIPropertyInfo(Of String)("Acctdesc", "Account description")), MyPropertyInfo(Of String))

Then in DP_Fetch you can set the original value and then set the current value: (the order is important!)
  AcctdescProperty.OrigValue = Trim(dr.GetString("acctdesc"))
  Me.LoadProperty(Of String)(AcctdescProperty, Trim(dr.GetString("acctdesc")))

===================================================================

Joe

Copyright (c) Marimer LLC