Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Building Serialization into Classes

0.00/5 (No votes)
24 Jun 2016 1  
Code that adds built-in serialization functionality to your classes in C#

Introduction

On a recent project I was working on, there was a requirement to save and load the state of various objects used by a database application. The solution was to add serialization functionality to the classes containing the application data.

The initial solution was to build a Visual Studio item template that could be used to quickly create classes that contained built-in capabilities of reading and writing the class property values via XML formatted files or strings.

A second solution was to build a generic class that takes any class type as a parameter and provides the same read/write XML functionality.

Both solutions provide serialization to files, strings and database tables. Methods that encrypt the serialized values are included for each type of serialization.

Class Template for Visual Studio

The .NET XML serialization namespace was used to provide the XML serialize/de-serialize functionality.

The System.Reflection namespace was used to provide methods that output the contents of the objects to non-XML formatted string values.

The attached source code does not include any binary or SOAP serialization functionality.

See the following link for the steps needed to add a custom project item template to the Add New Item dialog box:

C#
//
// Selected Save and Load methods from the Visual Studio class template for classes 
// with built-in serialization
//

public class ClassTemplateWithSerializers
{
.....

/// <summary>
/// Saves the column definitions contained in the current instance to the specified file. 
/// Serialization is used for the save.
/// </summary>
/// <param name="filePath">Full path for output file.</param>

public void SaveToXmlFile(string filePath)
{
       XmlSerializer ser = new XmlSerializer(typeof(ClassTemplateWithSerializers));
       TextWriter tex = new StreamWriter(filePath);
       ser.Serialize(tex, this);
       tex.Close();
}

/// <summary>
/// Creates and initializes an instance of the class by loading a serialized version 
/// of the instance from a file.
/// </summary>
/// <param name="filePath">Full path for the input file.</param>
/// <returns>An instance of ClassTemplateWithSerializers.</returns>
public static ClassTemplateWithSerializers LoadFromXmlFile(string filePath)
{
       XmlSerializer deserializer = new XmlSerializer(typeof(ClassTemplateWithSerializers));
       TextReader textReader = new StreamReader(filePath);
       ClassTemplateWithSerializers columnDefinitions;
       columnDefinitions = (ClassTemplateWithSerializers)deserializer.Deserialize(textReader);
       textReader.Close();
       return columnDefinitions;
}

Class Manager using Generics

If you do not wish to repeat the serialization logic in each class, you can use the ClassManager module. This module uses generics to accept an instance of a class type as a parameter to the constructor. Its methods then operate generically on the class instance.

C#
//
// Selected Save and Load methods from the generic class manager.
//

public class ClassManager<T>
{
.....
/// <summary>
/// Saves the column definitions contained in the current instance to the specified file. 
/// Serialization is used for the save.
/// </summary>
/// <param name="filePath">Full path for output file.</param>
public void SaveToXmlFile(string filePath)
{
       XmlSerializer ser = new XmlSerializer(typeof(T));
       TextWriter tex = new StreamWriter(filePath);
       ser.Serialize(tex, _classInstance);
       tex.Close();
}

/// <summary>
/// Creates and initializes an instance of the class by loading a serialized version 
/// of the instance from a file.
/// </summary>
/// <param name="filePath">Full path for the input file.</param>
/// <returns>An instance of the object.</returns>
public static T LoadFromXmlFile(string filePath)
{
       XmlSerializer deserializer = new XmlSerializer(typeof(T));
       TextReader textReader = new StreamReader(filePath);
       T columnDefinitions;
       columnDefinitions = (T)deserializer.Deserialize(textReader);
       textReader.Close();
       return columnDefinitions;
}

Using the Code

C#
//
// Examples that demonstrate the use of class instances derived from the Visual Studio template.
//

private static ClassWithSerializers _classWithSerializers = new ClassWithSerializers();
…..
classWithSerializers.IntValue = 25321;
…...
// Save class instance
_classWithSerializers.SaveToXmlFile(outputPath);
…..
//Retrieve saved instance into a new instance
ClassWithSerializers newObject = new ClassWithSerializers();
newObject = ClassWithSerializers.LoadFromXmlFile(outputPath);
C#
//
// Examples that demonstrate the use of the Class Manager to display the contents
// of an object instance that does not have built-in serialization.
//

private static ClassManager<TestClassNoSerializers> _classManager;
.....
//Save object to an XML file
_classManager.SaveToXmlFile(outputPath);
 ....
//Load object from instance saved in XML file
_classManager.SaveToXmlFile(outputPath);
newObject2 = ClassManager<TestClassNoSerializers>.LoadFromXmlFile(outputPath);
ClassManager<TestClassNoSerializers> clsmgr2 = new ClassManager<TestClassNoSerializers>(newObject2);
outputString = clsmgr2.ToXmlString();
.....

Points of Interest

Only XML serialization is used for this code. This approach was taken to help with troubleshooting any application issues.

Where security is required, serialization methods that use AES encryption were included in both the class template and generic class manager.

Saving to a database was coded by building methods that use the System.Data.Odbc functionality provided by .NET. In a real-world scenario, you could modify this code to use another .NET database provider.

History

This is the initial public release of the code.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here