473,385 Members | 1,357 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

BaseClass + DerivedClass + Serialization -- Dirty

Hi,

I have a BaseClass from which many Classes Derive.
In short: the BaseClass provides the functionalities (Methods) and the Derived Classes extend it with Properties.
One of the (Base) Functionalities is to (De)Serialize the Objects.

Deserialization is performed in the BaseClass
Friend Function PerformDeserialization(ByVal path As String, ByVal user As String) As Object
Debug.WriteLine("Settings.BaseSettings.PerformDese rialization")
If Not path.EndsWith("\") Then path += "\"
If user Is Nothing Then user = Me.ProductFamily
Dim cls As Object
If File.Exists(path + user + FilePrefix + CallerClass + ".xml") = True Then
Dim srFile As StreamReader = New StreamReader(path + user + FilePrefix + CallerClass + ".xml")
Dim t As Type
Dim pi As PropertyInfo()
Dim p As PropertyInfo
Try
xmlSerializer = New Xml.Serialization.XmlSerializer(Me.GetType())
cls = xmlSerializer.Deserialize(srFile)
t = cls.GetType
pi = t.GetProperties()
For Each p In pi
If p.PropertyType.Equals(GetType(System.String)) Then
p.SetValue(cls, Crypto.DecryptString(CType(p.GetValue(cls, Nothing), String)), Nothing)
End If
Next
Catch ex As Exception
Debug.WriteLine(ex.ToString) : Beep()
Finally
srFile.Close()
End Try
Else
Dim ClassType As Type = Me.GetType()
cls = Activator.CreateInstance(ClassType, True)
End If
InstanceHashCode = cls.GetHashCode
InstanceCreated = True
MarkClean(cls)
Return cls
End Function
An object is marked DIRTY by the Set of the Properties in the Derived Classes. (eg)
Private _connectionName As String
Public Property ConnectionName() As String
Get
Return _connectionName
End Get
Set(ByVal Value As String)
Debug.WriteLine("Settings.TestData.Set_ConnectionN ame")
If _connectionName = Value Then Exit Property
_connectionName = Value : MarkDirty(Me)
End Set
End Property
Serialization is called through the Public-Method 'Object'.Persist.
In that Sub I check the Flag IsDirty (Function in BaseClass) to determine if the Object *should* be Serialized or not.
Private mIsDirty As Boolean = False
Public Overridable ReadOnly Property IsDirty() As Boolean
Get
Return mIsDirty
End Get
End Property

The problem is that after Deserialization (I have Called MarkClean(cls)) all the properties seem to be re-Set (So they MarkDirty again). This is causing my Objects to be Always dirty. I can't seem to find a Point (within the (base)Class) to MarkClean effectively.

My guess is that this is Serialization-Behavior.

Does anyone have any ideas?

TIA,

Michael
Nov 20 '05 #1
10 1523
Hi Michael

Currently I am looking for somebody who could help you on it. We will reply
here with more information as soon as possible.
If you have any more concerns on it, please feel free to post here.
Thanks for your understanding!

Best regards,

Gary Chang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
--------------------

Nov 20 '05 #2
Hi Gary,

Thanks for your reply.
I'm looking foreward for any advise on this matter.

Kind regards,

Michael
Nov 20 '05 #3
Hi Michael,

I think we can try to set the TrackDirty to be false temporarily at the
beginning of PerformDeserialization and set it back to true at the end of
PerformDeserialization, so that the deserialize procedure will not call the
MarkDirty.

You may have a try and let me know the result.
Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 20 '05 #4
Hi Peter,

This seems to be impossible, because:
° 'Me' is another instance (There are 2: One of the default constructor
& one from the Desarialization)
° If you change a value from an object that's in the process of being
deserialized BEFORE it's returned to the Caller, then 'Nothing' gets
returned.

I think the problem is still unsolved here.

Kind regards,

Michael

""Peter Huang"" <v-******@online.microsoft.com> wrote in message
news:Kw*************@cpmsftngxa06.phx.gbl...
Hi Michael,

I think we can try to set the TrackDirty to be false temporarily at the
beginning of PerformDeserialization and set it back to true at the end of
PerformDeserialization, so that the deserialize procedure will not call the MarkDirty.

You may have a try and let me know the result.
Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 20 '05 #5
Michael,
Do you have a sample of where you call this code?

How are MarkDirty & MarkClean implemented, I would expect them to be
instance methods without parameters.

Private mIsDirty As Boolean = False
Public Overridable ReadOnly Property IsDirty() As Boolean
Get
Return mIsDirty
End Get
End Property

Protected Sub MarkDirty()
mIsDirty = True
End Sub

Protected Sub MarkClean()
mIsDirty = True
End Sub

I would expect PerformDeserialization to be a Shared method, otherwise it
appears that you need to create an instance of your object, to read an
instance of you object, where you throw away the first instance. With a
Shared method you will only create the instance that was read.

You do know you can use System.IO.Path.Combine to create path strings? &
System.IO.Path.ChangeExtension to add/replace the extension of a path
string?

path = System.IO.Path.Combine(path, user + FilePrefix + CallerClass)
path = System.IO.Path.ChangeExtension(path, ".xml")

In this case ChangeExtension may not be as useful, however Combine will
check for the trailing & leading path separators for you ("\" & "/").

Hope this helps
Jay
"Michael Maes" <mi*****@merlot.com> wrote in message
news:un*************@TK2MSFTNGP10.phx.gbl...
Hi,

I have a BaseClass from which many Classes Derive.
In short: the BaseClass provides the functionalities (Methods) and the
Derived Classes extend it with Properties.
One of the (Base) Functionalities is to (De)Serialize the Objects.

Deserialization is performed in the BaseClass
Friend Function PerformDeserialization(ByVal path As String, ByVal user As
String) As Object
Debug.WriteLine("Settings.BaseSettings.PerformDese rialization")
If Not path.EndsWith("\") Then path += "\"
If user Is Nothing Then user = Me.ProductFamily
Dim cls As Object
If File.Exists(path + user + FilePrefix + CallerClass + ".xml") = True
Then
Dim srFile As StreamReader = New StreamReader(path + user +
FilePrefix + CallerClass + ".xml")
Dim t As Type
Dim pi As PropertyInfo()
Dim p As PropertyInfo
Try
xmlSerializer = New
Xml.Serialization.XmlSerializer(Me.GetType())
cls = xmlSerializer.Deserialize(srFile)
t = cls.GetType
pi = t.GetProperties()
For Each p In pi
If p.PropertyType.Equals(GetType(System.String)) Then
p.SetValue(cls,
Crypto.DecryptString(CType(p.GetValue(cls, Nothing), String)), Nothing)
End If
Next
Catch ex As Exception
Debug.WriteLine(ex.ToString) : Beep()
Finally
srFile.Close()
End Try
Else
Dim ClassType As Type = Me.GetType()
cls = Activator.CreateInstance(ClassType, True)
End If
InstanceHashCode = cls.GetHashCode
InstanceCreated = True
MarkClean(cls)
Return cls
End Function
An object is marked DIRTY by the Set of the Properties in the Derived
Classes. (eg)
Private _connectionName As String
Public Property ConnectionName() As String
Get
Return _connectionName
End Get
Set(ByVal Value As String)
Debug.WriteLine("Settings.TestData.Set_ConnectionN ame")
If _connectionName = Value Then Exit Property
_connectionName = Value : MarkDirty(Me)
End Set
End Property
Serialization is called through the Public-Method 'Object'.Persist.
In that Sub I check the Flag IsDirty (Function in BaseClass) to determine if
the Object *should* be Serialized or not.
Private mIsDirty As Boolean = False
Public Overridable ReadOnly Property IsDirty() As Boolean
Get
Return mIsDirty
End Get
End Property

The problem is that after Deserialization (I have Called MarkClean(cls)) all
the properties seem to be re-Set (So they MarkDirty again). This is causing
my Objects to be Always dirty. I can't seem to find a Point (within the
(base)Class) to MarkClean effectively.

My guess is that this is Serialization-Behavior.

Does anyone have any ideas?

TIA,

Michael
Nov 20 '05 #6
Hi Michael,

I am sorry if I have any misunderstanding.
In addition to Jay's suggestion.
Now I want to restate the senario.
1. Use the StartMarkingDirty to set the TrackDirty to true, so that the
following changing to the object will set the IsDirty to true.
2. In the constructor to set the TrackDirty to true, in this way the
changing to the object will set the IsDirty to true including the
deserialization process which you do not want.
If I have any misunderstanding, please feel free to let me know.

Also by default, the deserialization will call the constructor to recreate
the object from the file, so now I think we have two approaches.
1. Use the StartMarkingDirty method to explicitly set the TrackDirty to
true.
2. in the contructor to know which one is call the constructor, if it is
the DeSerialization, then we can set the TrackDirty to false.
Public Sub New()
Debug.WriteLine("Settings.BaseSettings.New - Me.GetHashCode: "
& Me.GetHashCode.ToString)
Dim st As New StackTrace(True)
TrackDirty = True
If st.FrameCount >= 10 Then
Dim sf As StackFrame = st.GetFrame(10)
If sf.GetMethod().Name <> "PerformDeserialization" Then
TrackDirty = False
End If
End If
CallerClass = Me.GetType.Name.ToString.ToLower()
Crypto = New RijndaelSimple
End Sub

You may try the code below to print out all the callstack.
StackTrace Class
http://msdn.microsoft.com/library/de...us/cpref/html/
frlrfsystemdiagnosticsstacktraceclasstopic.asp
Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 20 '05 #7
Hi Jay,

Thanks for your reply.
It must be something silly here, but I'm so "Short-Circuited" on this that I can't see "the wood through the forrest" (if that's said in English) anymore.

I give you the two classes (Base & Derived) with all the methods of interest to this thread.

Option Strict Off
Imports System.IO
Imports System.Xml.Serialization
'Imports Stegosoft.Security
'Imports Stegosoft.Security.DotFuscator
Imports System.ComponentModel
Imports System.Reflection
Namespace Settings
''' -----------------------------------------------------------------------------
''' Project : StegoSettings
''' Class : Settings.BaseSettings
'''
''' -----------------------------------------------------------------------------
''' <summary>
'''
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [Michael.Maes] 6/12/2003 Created
''' [Michael.Maes] 30/06/2004 Transform to better OO
''' </history>
''' -----------------------------------------------------------------------------
'<Serializable(), _
'SkipRenaming(), _
'DebuggerStepThrough()> _
Public MustInherit Class BaseSettings
#Region " Declarations "
Private Shared xmlSerializer As xmlSerializer
Private Shared Crypto As RijndaelSimple
Private Shared FilePrefix As String = ".cfgsettings."
Protected Friend Shared CallingAssembly As [Assembly]
Private TrackDirty As Boolean = False
#End Region
#Region " Constructors "
Public Sub New()
Debug.WriteLine("Settings.BaseSettings.New - Me.GetHashCode: " & Me.GetHashCode.ToString)
Dim st As New StackTrace(True)
TrackDirty = True
If st.FrameCount >= 10 Then
Dim sf As StackFrame = st.GetFrame(10)
If sf.GetMethod().Name <> "PerformDeserialization" Then
TrackDirty = False
End If
End If
'CallerClass = Me.GetType.Name.ToString.ToLower()
'Crypto = New RijndaelSimple
End Sub
Friend Sub Instanciate()
Debug.WriteLine("Settings.BaseSettings.Instanciate ")
GetProductFamily()
GetCompany()
End Sub
Private Function GetProductFamily() As String
Debug.WriteLine("Settings.BaseSettings.GetProductF amily")
Dim t As Type = GetType(AssemblyDefaultAliasAttribute)
Dim r() As Object = CallingAssembly.GetCustomAttributes(t, False)
If IsNothing(r) Or r.Length = 0 Then
Return Nothing
Else
_ProductFamily = CType(r(0), AssemblyDefaultAliasAttribute).DefaultAlias
Return _ProductFamily
End If
End Function
Private Function GetCompany() As String
Debug.WriteLine("Settings.BaseSettings.GetCompany" )
Dim t As Type = GetType(AssemblyCompanyAttribute)
Dim r() As Object = CallingAssembly.GetCustomAttributes(t, False)
If IsNothing(r) Or r.Length = 0 Then
Return Nothing
Else
_Company = CType(r(0), AssemblyCompanyAttribute).Company
Return _Company
End If
End Function
#End Region
#Region " Properties "
Dim _ProductFamily As String = Nothing
Friend ReadOnly Property ProductFamily() As String
Get
If IsNothing(_ProductFamily) Then _ProductFamily = GetProductFamily()
Return _ProductFamily
End Get
End Property
Dim _Company As String = Nothing
Friend ReadOnly Property Company() As String
Get
If IsNothing(_Company) Then _Company = GetCompany()
Return _Company
End Get
End Property
Public Sub StartMarkingDirty() 'ByVal Instance As Object)
Debug.WriteLine("Settings.BaseSettings.StartMarkin gDirty".ToUpper & Me.GetHashCode)
TrackDirty = True
End Sub
Private mIsDirty As Boolean = False
Public Overridable ReadOnly Property IsDirty() As Boolean
Get
Return mIsDirty
End Get
End Property
Protected Sub MarkDirty()
Debug.WriteLine("Settings.BaseSettings.MarkDirty")
If TrackDirty Then mIsDirty = True
End Sub
Protected Sub MarkClean()
mIsDirty = False
End Sub

#End Region
#Region " Load "
'Public Overridable Function Load(ByVal path As String, Optional ByVal user As String = Nothing) As Object
' Debug.WriteLine("Settings.BaseSettings.Load")
' Return PerformDeserialization(path, user)
'End Function
Friend Shared Function PerformDeserialization(ByVal CallerClass As Object, ByVal path As String, ByVal user As String) As Object
Debug.WriteLine("Settings.BaseSettings.PerformDese rialization")
If Not path.EndsWith("\") Then path += "\"
If user Is Nothing Then user = CallerClass.ProductFamily
Dim cls As Object
If File.Exists(path + user + FilePrefix + CallerClass.GetType.Name.ToString.ToLower() + ".xml") = True Then
Debug.WriteLine("Settings.BaseSettings.New - Me.GetHashCode: " & CallerClass.GetHashCode.ToString)
Crypto = New RijndaelSimple
Dim srFile As StreamReader = New StreamReader(path + user + FilePrefix + CallerClass.GetType.Name.ToString.ToLower() + ".xml")
Dim t As Type
Dim pi As PropertyInfo()
Dim p As PropertyInfo
Try
xmlSerializer = New Xml.Serialization.XmlSerializer(CallerClass.GetTyp e())
cls = xmlSerializer.Deserialize(srFile)
t = cls.GetType
pi = t.GetProperties()
For Each p In pi
If p.PropertyType.Equals(GetType(System.String)) Then
'p.SetValue(cls, Crypto.DecryptString(CType(p.GetValue(cls, Nothing), String)), Nothing)
p.SetValue(cls, (CType(p.GetValue(cls, Nothing), String)), Nothing)
End If
Next
Catch ex As Exception
Debug.WriteLine(ex.ToString)
MsgBox(ex.ToString)
Finally
srFile.Close()
End Try
Else
Dim ClassType As Type = CallerClass.GetType()
cls = Activator.CreateInstance(ClassType, True)
End If
Return cls
End Function
#End Region
#Region " Persist "
Public Sub Persist(ByVal path As String, Optional ByVal user As String = Nothing)
Debug.WriteLine("Settings.BaseSettings.Persist")
If user Is Nothing Then user = Me.ProductFamily
PerformSerialization(Me, path, user)
End Sub
Private Sub PerformSerialization(ByVal CallerClass As Object, ByVal path As String, ByVal user As String)
Debug.WriteLine("Settings.BaseSettings.PerformSeri alization")
If Not path.EndsWith("\") Then path += "\"
Dim FileName As String = path + user.ToLower + FilePrefix + CallerClass.GetType.Name.ToString.ToLower() + ".xml"
Dim swFile As StreamWriter = New IO.StreamWriter(FileName)
Dim t As Type = Me.GetType()
Dim pi As PropertyInfo()
Dim p As PropertyInfo
pi = t.GetProperties()
' Encrypt Strings
For Each p In pi
If p.PropertyType.Equals(GetType(System.String)) Then
'p.SetValue(Me, Crypto.EncryptString(CType(p.GetValue(Me, Nothing), String)), Nothing)
p.SetValue(Me, (CType(p.GetValue(Me, Nothing), String)), Nothing)
End If
Next
' Save to Disk
xmlSerializer = New Xml.Serialization.XmlSerializer(t)
xmlSerializer.Serialize(swFile, Me)
swFile.Close()
End Sub
#End Region
End Class
End Namespace

--------------------------------------------------------------------------------

Namespace Settings
''' -----------------------------------------------------------------------------
''' Project : StegoSettings
''' Class : Settings.TestData
'''
''' -----------------------------------------------------------------------------
''' <summary>
'''
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' [Michael.Maes] 6/12/2003 Created
''' [Michael.Maes] 30/06/2004
''' </history>
''' -----------------------------------------------------------------------------
<Serializable()> Public Class TestData
Inherits Settings.BaseSettings
'Public Sub New()
' MyBase.New()
' Debug.WriteLine("Settings.TestData.New - Me.GetHashCode: " & Me.GetHashCode.ToString)
' CallingAssembly = Me.GetType.Assembly.GetCallingAssembly
' MyBase.Instanciate()
'End Sub
#Region " Load "
Public Shadows Function Load(ByVal path As String, Optional ByVal user As String = Nothing) As TestData
Debug.WriteLine("Settings.TestData.Load")
Try
'StartMarkingDirty()
Debug.WriteLine("Settings.TestData.New - Me.GetHashCode: " & Me.GetHashCode.ToString)
CallingAssembly = Me.GetType.Assembly.GetCallingAssembly
MyBase.Instanciate()
Dim cls As TestData = DirectCast(PerformDeserialization(Me, path, user), TestData)
Debug.WriteLine("************** cls Calling StartMarkingDirty: " & cls.GetHashCode)
StartMarkingDirty()
Return cls
Catch ex As Exception
Return Nothing
End Try
End Function
#End Region
Private _connectionName As String
Public Property ConnectionName() As String
Get
Return _connectionName
End Get
Set(ByVal Value As String)
Debug.WriteLine("Settings.TestData.Set_ConnectionN ame")
_connectionName = Value : MarkDirty()
End Set
End Property
End Class
End Namespace
--------------------------------------------------------------------------------
I'dd be more than greatfull if you'd come up with a solution.

Kind regards,

Michael
Nov 20 '05 #8
Hi Michael,

I do your first question, than can Jay take the rest again (I did not follow
this thread), however that one about the trees I found funny. I think it is
"Unable to see the wood for the trees", the same as with us I thought (I
have this from a book full of those, however far from complete).

Cor
Nov 20 '05 #9
Cor,
Actually its "Unable to see the forest for the trees".

http://www.wordwizard.com/clubhouse/...1.asp?Num=3769

I actually like John Pursel's variation.

Although Wood & Forest can be synonymous

Jay

"Cor Ligthert" <no**********@planet.nl> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Hi Michael,

I do your first question, than can Jay take the rest again (I did not follow this thread), however that one about the trees I found funny. I think it is "Unable to see the wood for the trees", the same as with us I thought (I
have this from a book full of those, however far from complete).

Cor

Nov 20 '05 #10
I think (hope) my dutch is better then my english.....

I am in the middle of founding a new company, moving our office, hire staff,
..... so I guess that's a lousy excuse for messing things up :-(

Michael
Nov 20 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: verbatime | last post by:
Please explain me how this works - or should work: Got my two classes - bcBasic (baseclass) and the derived cBasic. //--------------------------------------- class bcBasic { int number;...
3
by: jamie_m_ | last post by:
I have a custom collection ... clFile that INHERITS from NameObjectCollectionBase the problem is, when I try to create an xmlserializer instance i get an error You must implement a default...
15
by: Rey | last post by:
Howdy all. Appreciate your help with several problems I'm having: I'm trying to determine if the Visit subform (subformVisits) has a new record or been changed, i.e. dirty. The form that...
2
by: Salad | last post by:
A97. I have a command button to save and exit. I had the code If Me.Dirty Then Docmd.RunCommand acCmdSaveRecord ...more code endif I was getting an error because a value was not getting...
9
by: Susan Bricker | last post by:
I am currently using the OnDirty event of a Form to detect whether any fields have been modified. I set a boolean variable. Then, if the Close button is clicked before the Save button, I can put...
4
by: Kimmo Laine | last post by:
Hi, is there a way to hide baseclass members: class BaseClass { public BaseClass() {} public string Get() { return "base"; } } class MyClass: BaseClass {
1
by: jamie_m_ | last post by:
I have a custom collection ... clFile that INHERITS from NameObjectCollectionBase the problem is, when I try to create an xmlserializer instance i get an error You must implement a default...
10
by: SStory | last post by:
My app is near completed for the basic feature of version 1.0. I have an extensive object model and I now want to persist my objects using serialization. I have chosen binaryformatter to...
3
by: Michael Maes | last post by:
Hi, I have a BaseClass-DerivedClass Instance-Issue. Classes: (Framework) Stegosoft.Settings.SerializationClass Stegosoft.Stegosuite.Common.UIStrings (Inherits...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.