Mapping structures or a Reflection solution

  • Thread starter Thread starter Victory
  • Start date Start date
V

Victory

Hi,
I have an application in C# which writes a structure that
the user compiles/enters to a file on disk. Now, the initial
version of the application (version 1.0) uses a structure
that has x number of members. When a new request for change
comes up that requires a change in the structure i have to
add a new member to the structure (hence version 2.0). The
users who created their saved data structure with version
1.0 now want to open their files and those who are creating
new files, will be written data onto the disk with structure
of version 2.0. How do i make the program to read the data
and map what is read to the correct structure? The
structure contains a number of strings, ints, Classes,
Hashtables, as well as List<Classes> and so forth. So, i am
writting the structure as binary (serialized) to disk and
obviously reading back the same way.
In code, i have to do this type (psudeo):

- Find the version of file
- if version 1.o, open the file using structure version 1.o,
cast it to the correct structure type.
- if version 2.o, open the file using structure version 1.o,
cast it to the correct structure type.

now, when i want to process the information in the structure
(like traverse it and display it, etc.), i want to use the
same structure regardless of the structure. Is there a way
using Reflections to do this that makes things easier?
thanks,
Mars
 
Hi,
I have an application in C# which writes a structure that
the user compiles/enters to a file on disk. Now, the initial
version of the application (version 1.0) uses a structure
that has x number of members. When a new request for change
comes up that requires a change in the structure i have to
add a new member to the structure (hence version 2.0). The
users who created their saved data structure with version
1.0 now want to open their files and those who are creating
new files, will be written data onto the disk with structure
of version 2.0. How do i make the program to read the data
and map what is read to the correct structure? [...]

It depends on how you're actually serializing the data. But, the built-in
serialization support (at least some of it) includes versioning support,
which would handle this automatically.

If you're doing the serialization manually, then you also have to take
care of versioning manually. Again, how specifically to do that will
depend on how exactly you're serializing the data.

That's about as specific an answer as is possible given the level of
detail in your question.

Pete
 
Pete,
I am not doing the serialization manually. I am using an
instance of the BinaryFormatter with a stream to the filename
to be written and the instance of the structure to be written.
When reading i am doing the same with a deserialize method of
a BinaryFormatter instance with a stream pointing to the
filename. The Deserialize method is then casted to a structure
internally. How is the versioning handled for me? If i cast
the Deserialize method to one object and the file has a
structure that uses a different structure, the cast will fail.

thanks,
Mars
 
Pete,
I am not doing the serialization manually. I am using an
instance of the BinaryFormatter with a stream to the filename
to be written and the instance of the structure to be written.
When reading i am doing the same with a deserialize method of
a BinaryFormatter instance with a stream pointing to the
filename. The Deserialize method is then casted to a structure
internally. How is the versioning handled for me? If i cast
the Deserialize method to one object and the file has a
structure that uses a different structure, the cast will fail.

See http://msdn.microsoft.com/en-us/library/ms229752(VS.80).aspx

The old way:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationbinder.aspx

Again, unless you provide specific details (in the form of a
concise-but-complete code example), a more detailed answer can't be
provided.

Pete
 
Below is an example. First version of the application will
have the following structure to write to disk:

[Serializable]
public class ExampleClass
{
private int _lotId;

class example()
{
_lotId = -1;
}

private int LotID
{
get { return _lotId; }
set
{
_lotId = value;
}

public bool Save()
{
string dPath = "c:\temp";
FileStream dFileStream = null;
BinaryFormatter dbinaryFormatterObject = null;

try
{
dFileStream = new FileStream(dPath, FileMode.Create);

dbinaryFormatterObject = new BinaryFormatter();
dbinaryFormatterObject.Serialize(dFileStream, this);
}
catch(SerializationException ex)
{
// log the exception
return false;
}
finally
{
if (dFileStream)
{
dFileStream.Flush();
dFileStream.Close();
}
}
return true;
}

public bool Read()
{
BinaryFormatter dBFObj = null;
FileStream dFileStream = null;

try
{
FileInfo fileInfo = new FileInfo(dPath);
if (fileInfo.Exists)
{
dFileStream = new FileStream(dPath, FileMode.Open);

dBFObj = new BinaryFormatter();

dFileStream.Position = 0;

ExampleClass exampleObj =
(ExampleClass)dBFObj.Deserialize(dFileStream);
}
catch(Exception e)
{
// log the error
return false;
}
return true;
}

}

A request came in to add additional fields to the structure,
now the program has to read both the old formatted files and
the new ones. Here is the new structure.

[Serializable]
public class ExampleClass
{
private int _lotId;
private string _locationName;
private List<string> _clientInfo;

class example()
{
_lotId = -1;
_locationName = string.Empty;
_clientInfo = new List<string>();
}

private int LotID
{
get { return _lotId; }
set
{
_lotId = value;
}


private string LocationName
{
get { return _locationName; }
set
{
_locationName = value;
}


private List<string> ClientInfo
{
get { return _clientInfo; }
set
{
_clientInfo = value;
}
}

// the save and read functions are the same as above.
}

In order for the program to read both versions, i have to
change the name of the second ExampleClass to something
else, read the file and check the version and cast the
deserialize method into the correct version of the object.
Is this the only way? Or is there a better way?
thank you,
Mars
 
Below is an example. First version of the application will
have the following structure to write to disk:

[Serializable]
public class ExampleClass
{
private int _lotId;

class example()
{
_lotId = -1;
}

private int LotID
{
get { return _lotId; }
set
{
_lotId = value;
}

public bool Save()
{
string dPath = "c:\temp";
FileStream dFileStream = null;
BinaryFormatter dbinaryFormatterObject = null;

try
{
dFileStream = new FileStream(dPath, FileMode.Create);

dbinaryFormatterObject = new BinaryFormatter();
dbinaryFormatterObject.Serialize(dFileStream, this);
}
catch(SerializationException ex)
{
// log the exception
return false;
}
finally
{
if (dFileStream)
{
dFileStream.Flush();
dFileStream.Close();
}
}
return true;
}

public bool Read()
{
BinaryFormatter dBFObj = null;
FileStream dFileStream = null;

try
{
FileInfo fileInfo = new FileInfo(dPath);
if (fileInfo.Exists)
{
dFileStream = new FileStream(dPath, FileMode.Open);

dBFObj = new BinaryFormatter();

dFileStream.Position = 0;

ExampleClass exampleObj =
(ExampleClass)dBFObj.Deserialize(dFileStream);
}
catch(Exception e)
{
// log the error
return false;
}
return true;
}

}

A request came in to add additional fields to the structure,
now the program has to read both the old formatted files and
the new ones. Here is the new structure.

[Serializable]
public class ExampleClass
{
private int _lotId;
private string _locationName;
private List<string> _clientInfo;

class example()
{
_lotId = -1;
_locationName = string.Empty;
_clientInfo = new List<string>();
}

private int LotID
{
get { return _lotId; }
set
{
_lotId = value;
}


private string LocationName
{
get { return _locationName; }
set
{
_locationName = value;
}


private List<string> ClientInfo
{
get { return _clientInfo; }
set
{
_clientInfo = value;
}
}

// the save and read functions are the same as above.
}

In order for the program to read both versions, i have to
change the name of the second ExampleClass to something
else, read the file and check the version and cast the
deserialize method into the correct version of the object.
Is this the only way? Or is there a better way?
thank you,
Mars
 
[...]
In order for the program to read both versions, i have to
change the name of the second ExampleClass to something
else, read the file and check the version and cast the
deserialize method into the correct version of the object.
Is this the only way? Or is there a better way?

If you have to support files already written, you may be stuck. However,
..NET does provide versioning support. Please read the links I offered
earlier.
 
Back
Top