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