Serialization Question

webdev_mu

New member
Joined
Jan 16, 2009
Messages
4
Programming Experience
5-10
Running into an issue with some functionality I'm trying to develop.

Client uses a series of Business objects (entities like Order, Customer, etc) that all inherit from the MustInherit class called AbstractEntity. There is a desire to add some logging/audit functionality to this class, so that all the objects will have it. Essentially, we want this:

--Edits Begin

--A copy of the object is written out via binary serialization

--Properties are changed



Then, there are two paths:



EndEdit is called

--insert entries to logging table

--discard the binary copy



Or

CancelEdit is called

The values in the binary copy should be restored, in effect, discarding the edits



I thought I could implement IEditiableObject on the AbstractEntity class, since the methods exposed seem to fit perfectly with what we are trying to capture, but I am having difficulty envisioning how to handle the CancelEdit method -- how can I take a Byte() and use it to overwrite the values of the object itself? Esp. since I'm in the Abstract class, and not a concrete instance.

For example, the Customer class could have properties like FirstName, LastName, and RegisterDate. When BeginEdit is called, I make a binary copy of the object, and store it in a private property of the AbstractEntity Class.

What can I do so that when CancelEditis called, the binary copy is "restored"?



Here is the code of the AbstractEntity class

VB.NET:
1    Option Strict On
2    Option Explicit On
3    
4    Imports System.ComponentModel
5    Imports System.Runtime.Serialization.Formatters.Binary
6    Imports System.IO
7    
8    Public MustInherit Class AbstractEntity
9        Implements IEditableObject
10       'this class contains the common properties that all business objects will share
11       'this includes items like the objects state
12   
13       Private _state As Integer
14       Private _binData As Byte()
15       Private _memStream As MemoryStream
16       Private _binFormat As BinaryFormatter
17   
18       Public Enum ObjectStateEnum As Integer
19           UNCHANGED = 0
20           CHANGED = 1
21           CHANGING = 2
22       End Enum
23   
24       Sub BeginEdit() Implements IEditableObject.BeginEdit
25           'here we will store a serialized version of the object -- before edit
26           'Set state to Changing
27           _memStream = New MemoryStream
28           _binFormat = New BinaryFormatter
29   
30           _binFormat.Serialize(_memStream, Me)
31           _binData = _memStream.ToArray()
32           _state = ObjectStateEnum.CHANGING
33       End Sub
34   
35       Sub CancelEdit() Implements IEditableObject.CancelEdit
36           'we would restore the values of our serialized copy
37           _memStream = New MemoryStream(_binData)
38           _binFormat = New BinaryFormatter
39   
40           _binFormat.Deserialize(_memStream)
41           _state = ObjectStateEnum.UNCHANGED
42       End Sub
43   
44       Sub EndEdit() Implements IEditableObject.EndEdit
45           'Accept Edit.  Object has Changed.
46           _state = ObjectStateEnum.CHANGED
47       End Sub
48   
49       Public Property ObjectState() As ObjectStateEnum
50           Get
51               Return CType(_state, ObjectStateEnum)
52           End Get
53           Set(ByVal value As ObjectStateEnum)
54               _state = value
55           End Set
56       End Property
57       Public ReadOnly Property HasChanges() As Boolean
58           Get
59               If _state = ObjectStateEnum.CHANGED Then
60                   Return True
61               Else
62                   Return False
63               End If
64           End Get
65       End Property
66   
67   End Class

Code above doesn't include the EndEit implementation, or a full CancelEdit.



TIA
 
Hello.

I think it should be something like this:
VB.NET:
35       Sub CancelEdit() Implements IEditableObject.CancelEdit
36           'we would restore the values of our serialized copy
37           _memStream = New MemoryStream(_binData)
38           _binFormat = New BinaryFormatter
39   
40           Dim deser_copy as AbstractEntity = _binFormat.Deserialize(_memStream, AbstractEntity)
41           _state = ObjectStateEnum.UNCHANGED
42       End Sub

The Problem is that deser_copy is a whole class itself, means that you need to overwrite Me with it...which is a little difficult.

Bobby
 
webdev_mu said:
overwrite the values of the object itself?
You can't change the class instance from within the class code (Me can't be target of assignment), only the property values can be changed. .Net library only has one implementation of IEditableObject that I know of, the DataRowView, it holds the data of a DataRow. How it does this is beside the point, but it is the data row values that is backed up and replaced, not the DataRowView itself. If you want to get the properties and values of inherited classes you must look into reflection to discover them. So you can do one of three; use a "view" wrapper class that hold the data object, or keep data in some kind of column based key/value lookup table, or use reflection to handle inherited classes properties at runtime.
 
Appriciate the responses. I had assumed I would indeed need to use Reflection, but wanted to see if I missed some more appealing way to do it. I will see about wrapping the data, however, as to which approach will work the best for us.

Thanks!
 
Back
Top