8.5 Custom Serialization

only for RuBoard

Only public, read/write fields are serialized to XML, while binary serialization puts everything but the kitchen sink into the stream. Does this seem a little extreme? If more control is needed or if the default behavior doesn't do what needs to be done, the ISerializable interface provides an object with the means to control its own serialization. Implementing the interface is surprisingly simple. The interface contains a single method, called GetObjectData , with the following signature:

 Sub GetObjectData(ByVal  info  As  SerializationInfo  , _                   ByVal  context  As  StreamingContext  ) 

8.5.1 SerializationInfo

As shown in Example 8-14, the first parameter to the GetObjectData method is a class called SerializationInfo that contains a method named AddValue . AddValue is overloaded to take all the native types from the System namespace, including Object and Type . Just pass it the data that needs to be serialized. Data is passed as a key-value pair so that values can be retrieved in any order (by name ) during deserialization. Anything can be added to the stream, and additional business logic is easily incorporated.

Example 8-14. Implementing ISerializable, Part I
 Imports System Imports System.IO Imports System.Runtime.Serialization Imports System.Runtime.Serialization.Formatters.Binary     <Serializable( )> _ Public Class Employee     Implements ISerializable  Private Sub GetObjectData(ByVal info As SerializationInfo, _   ByVal context As StreamingContext) _   Implements ISerializable.GetObjectData   info.AddValue("First", FirstName)   info.AddValue("Last", LastName)   info.AddValue("Dept", Department)   LastAccessed = DateTime.Now   info.AddValue("AccessDate", LastAccessed)   End Sub  Public employeeID As Integer 'Primary key in database     Public FirstName As String     Public LastName As String     Public Department As String     Public LastAccessed As Date     End Class     Public Class Test         Public Shared Sub Main( )         Dim empIn As New Employee( )         empIn.employeeID = 19283         empIn.FirstName = "Lex"         empIn.LastName = "Luthor"         empIn.Department = "Operations"             Dim formatter As New BinaryFormatter( )         Dim stream As New FileStream("employee.bin", _                             FileMode.Create, _                             FileAccess.ReadWrite)         formatter.Serialize(stream, empIn)                  'Leave stream open for now         End Sub     End Class 

ISerializable is somewhat special. For the process to work, a constructor with the same signature as GetObjectData must exist; this is where deserialization occurs. The use of this constructor is illustrated in Example 8-15, which both serializes and deserializes the Employee object. A side effect of adding this constructor is that a default constructor must now be declared explicitly. Values are retrieved in a manner similar to the way binary readers retrieve values. The incoming SerializationInfo instance contains several methods named with the following format: Get datatype , where datatype is a type defined in the System namespace. Each method takes the name of the parameter that is needed (which must match the key parameter in the AddValue call).

Example 8-15. Implementing ISerializable, Part II
 Imports System Imports System.IO Imports System.Runtime.Serialization Imports System.Runtime.Serialization.Formatters.Binary     <Serializable( )> _ Public Class Employee     Implements ISerializable  Public Sub New( )  '  Empty   End Sub   'Assure this constructor is not available in the public interface of   'the class by making it a friend   Friend Sub New(ByVal info As SerializationInfo, _   ByVal context As StreamingContext)   FirstName = info.GetString("First")   LastName = info.GetString("Last")   Department = info.GetString("Dept")   LastAccessed = info.GetDateTime("AccessDate")   End Sub  Private Sub GetObjectData(ByVal info As SerializationInfo, _                               ByVal context As StreamingContext) _                               Implements ISerializable.GetObjectData             info.AddValue("First", FirstName)         info.AddValue("Last", LastName)         info.AddValue("Dept", Department)             LastAccessed = DateTime.Now         info.AddValue("AccessDate", LastAccessed)         End Sub         Public employeeID As Integer 'Primary key in database     Public FirstName As String     Public LastName As String     Public Department As String     Public LastAccessed As Date     End Class     Public Class Test         Public Shared Sub Main( )             Dim empIn As New Employee( )         empIn.employeeID = 19283         empIn.FirstName = "Lex"         empIn.LastName = "Luthor"         empIn.Department = "Operations"             Dim formatter As New BinaryFormatter( )         Dim stream As New FileStream("employee.bin", _                             FileMode.Create, _                             FileAccess.ReadWrite)         formatter.Serialize(stream, empIn)             '  Position stream back to the beginning   stream.Seek(0, SeekOrigin.Begin)   Dim empOut As Employee = _   CType(formatter.Deserialize(stream), Employee)   Console.WriteLine(empOut.FirstName)   Console.WriteLine(empOut.LastName)   Console.WriteLine(empOut.Department)   Console.WriteLine("Last Access: {0}", _   empOut.LastAccessed.ToShortDateString)   Console.ReadLine( )  End Sub     End Class 

8.5.2 SerializationContext

The SerializationContext parameter of GetObjectData (and the matching constructor) describes the target or source context for a serialization stream. This class's State property can be one or more values from StreamingContextState , whose primary values are CrossAppDomain , CrossMachine , CrossProcess , and File . Other values are available, but they do not pertain here.

This context parameter is useful because the serialization and deserialization process might have to be altered based on where the serialization stream comes from or where it is headed. This parameter describes the circumstances under which serialization and deserialization take place, providing the opportunity to exclude irrelevant data. For example:

 Public Sub New (ByVal  info  As  SerializationInfo  , _                 ByVal  context  As  StreamingContext  )         If context.State = StreamingContextStates.CrossMachine Then         'Do not serialize machine specific data     Else         'Serialize it     End If         If context.State = StreamingContextStates.CrossProcess Then         'Do not serialize process specific data     Else         'Serialize it     End If . . . End Sub 
only for RuBoard


Object-Oriented Programming with Visual Basic. Net
Object-Oriented Programming with Visual Basic .NET
ISBN: 0596001460
EAN: 2147483647
Year: 2001
Pages: 112
Authors: J.P. Hamilton

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net