# How to serialize objects (Part 2)

In my previous [post](http://blogs.voxelbusters.com/products/runtime-serialization/how-to-serialize-part1), we looked into topics such as modifying scripts to make it RS compatible and passing infomation about the properties that needs to be serialized. But everytime it wont be possible to modify scripts to make it compatible with our plugin.

Consider the case wherein we want to serialize an instance of a class which belongs to external assembly. By default, serialization of these objects will fail as class is not marked [RuntimeSerializable](http://voxel-busters-interactive.github.io/Runtime-Serialization/Documentation/DoxygenOutput/html/class_voxel_busters_1_1_runtime_serialization_1_1_runtime_serializable_attribute.html) and even it doesn’t pass on information about properties that needs to be serialized. So viable solution for this problem is to delegate object’s serialization control to some other object. We call this delegated object as Extension. So basically Extension class controls serialization and deserialization of target object.

## Working of Extension class

Firstly, Extension class must have same class name as target type with suffix RSExtension. At the time of serialization of an non [RuntimeSerializable](http://voxel-busters-interactive.github.io/Runtime-Serialization/Documentation/DoxygenOutput/html/class_voxel_busters_1_1_runtime_serialization_1_1_runtime_serializable_attribute.html) class, RS makes use of Reflection to check if Extension class for target type exists or not. If it does exist then object of that extension class is used fo handling serialization and deserialization of target object.

Its even possible to manually map object to its Extension by calling AddNewExtension method of RSExtensionManager. Simple advantage of following this step is that, Reflection for finding associated Extension at runtime is skipped for this particular object type.

Similar to c# object serialization, even Extension class, serialization can be carried out using Attributes as well as by using [IRuntimeSerializableExtension](http://voxel-busters-interactive.github.io/Runtime-Serialization/Documentation/DoxygenOutput/html/interface_voxel_busters_1_1_runtime_serialization_1_1_i_runtime_serialization_extension.html). This decision is totally dependent on target object’s class structure.

## Extension class serialization Using Attributes

Lets have a look into [Vector2](http://docs.unity3d.com/ScriptReference/Vector2.html) You might be aware that, [Vector2](http://docs.unity3d.com/ScriptReference/Vector2.html) belongs to external assembly UnityEngine. And by default, this type is not compatible with RS. So definitely serialization of [Vector2](http://docs.unity3d.com/ScriptReference/Vector2.html) class will fail and moreover its not possible to modify its class definition inorder to make it serializable. So for situations like theses, we need to implement Extensions. In \[Vector2]\(<http://docs.unity3d.com/ScriptReference/Vector2.html>, pubic fields x and y holds the value of this object. Thereby for serializing [Vector2](http://docs.unity3d.com/ScriptReference/Vector2.html) object, we just need to serialize these 2 field values. object structure.

```
namespace UnityEngine
{
    public struct Vector2
    {
        //
        // Static Fields
        //
        public const float kEpsilon = 1E-05f;

        //
        // Fields
        //
        public float y;

        public float x;

        .
        .
        .
    }    
}
```

You might be aware that, [Vector2](http://docs.unity3d.com/ScriptReference/Vector2.html) belongs to external assembly UnityEngine. And by default, this type is not compatible with RS. So definitely serialization of [Vector2](http://docs.unity3d.com/ScriptReference/Vector2.html) class will fail and moreover its not possible to modify its class definition inorder to make it serializable. So for situations like theses, we need to implement Extensions.

In [Vector2](http://docs.unity3d.com/ScriptReference/Vector2.html), pubic fields x and y holds the value of this object. Thereby for serializing \[Vector2]\(<http://docs.unity3d.com/ScriptReference/Vector2.htm> object, we just need to serialize these 2 field values. This can be done easily using RuntimeSerializable object with an override flag to serialize all public fields of target object.

Following code example shows Extension implementation for [Vector2](http://docs.unity3d.com/ScriptReference/Vector2.html) struct.

```
[RuntimeSerializable(true)]
public class Vector2RSExtension
{}
```

## Extension class serialization Using IRuntimeSerializableExtension

Now lets move to the next topic, i.e, writing Extensions by implementing [IRuntimeSerializableExtension](http://voxel-busters-interactive.github.io/Runtime-Serialization/Documentation/DoxygenOutput/html/interface_voxel_busters_1_1_runtime_serialization_1_1_i_runtime_serialization_extension.html) class. Serialization using this option, will provide complete control over serialization and deserialization of an object which belongs to external assembly. And FYI, this implementation overrides reflection based serialization process as well.

Lets have a brief overview of the methods provided by this abstract class:

### Write Serialization Data

In terms of functionality, its very much similar to [WriteSerializationData](http://voxel-busters-interactive.github.io/Runtime-Serialization/Documentation/DoxygenOutput/html/interface_voxel_busters_1_1_runtime_serialization_1_1_i_runtime_serializable.html#ad0d562a5e94e40838224b0a126f87c43) call of [IRuntimeSerializable](http://voxel-busters-interactive.github.io/Runtime-Serialization/Documentation/DoxygenOutput/html/interface_voxel_busters_1_1_runtime_serialization_1_1_i_runtime_serializable.html) interface. Basically you need to populate [RuntimeSerializationInfo](http://voxel-busters-interactive.github.io/Runtime-Serialization/Documentation/DoxygenOutput/html/class_voxel_busters_1_1_runtime_serialization_1_1_runtime_serialization_info.html) with the properties of the target object. And at the point of serializing target object, all the properties added to this collection are serialized.

### Create Instance

Internally, RS creates object instances by making use of Reflection. But sometimes it does fail, when it tries to create instance for object types which dont expose default constructors. For eg: Texture2D. However no need to worry! we have got it covered. Make use of this method to provide custom definition to create a new instance of target object.

### Read Serialization Data

Even this method behaves similarly to [ReadSerializationData](http://voxel-busters-interactive.github.io/Runtime-Serialization/Documentation/DoxygenOutput/html/interface_voxel_busters_1_1_runtime_serialization_1_1_i_runtime_serialization_extension.html#ad7cbc4dec1138fee757be8e783e4f323) call of [IRuntimeSerializable](http://voxel-busters-interactive.github.io/Runtime-Serialization/Documentation/DoxygenOutput/html/interface_voxel_busters_1_1_runtime_serialization_1_1_i_runtime_serializable.html) interface. Here this method gets called after retrieving all the properties that were previously serialized. And your job is to assign these values back to the target object instance. Thats it! Now your target object is deserialized back to its former state. Following code sample shows serialization of Rect class using [IRuntimeSerializableExtension](http://voxel-busters-interactive.github.io/Runtime-Serialization/Documentation/DoxygenOutput/html/interface_voxel_busters_1_1_runtime_serialization_1_1_i_runtime_serialization_extension.html).

```
using UnityEngine;
using System.Collections;
using VoxelBusters.RuntimeSerialization;

public class RectRSExtension : IRuntimeSerializableExtension
{
    #region Constants

    private     const    string        kOriginXKey            = "x";
    private     const    string        kOriginYKey            = "y";
    private     const    string        kWidthKey            = "w";
    private     const    string        kHeightKey            = "h";

    #endregion

    #region Serialization Methods

    public override void WriteSerializationData (object _object, RuntimeSerializationInfo _info)
    {
        Rect    _rect    = (Rect)_object;

        // Serialize properties
        _info.AddValue<float>(kOriginXKey,     _rect.x);
        _info.AddValue<float>(kOriginYKey,    _rect.y);
        _info.AddValue<float>(kWidthKey,     _rect.width);
        _info.AddValue<float>(kHeightKey,     _rect.height);
    }

    public override object ReadSerializationData (object _object, RuntimeSerializationInfo _info)
    {
        Rect    _rect    = (Rect)_object;

        // Deserialize properties
        _rect.x        = _info.GetValue<float>(kOriginXKey);
        _rect.y        = _info.GetValue<float>(kOriginYKey);
        _rect.width    = _info.GetValue<float>(kWidthKey);
        _rect.height    = _info.GetValue<float>(kHeightKey);

        return _rect;
    }

    #endregion
}
```
