26 de marzo de 2014

Serialize C#

En muchas de nuestras aplicaciones cuando la funcionalidad que damos se vuelve cada día mayor es necesario intercambiar información digamos más compleja que un simple dato de tipo carácter o numérico, podemos pensar quizá en los datos completos de un empleado (nombre, edad, domicilio, RFC, foto, etc...) o incluso una colección de ellos. Este intercambio puede ser entre aplicaciones, a nivel de Base de datos, usando la misma plataforma que la nuestra o incluso una distinta y con plataforma me refiero no solo al sistema operativo, sino que también a la tecnología con la que estamos desarrollando. ¿Qué sucederá cuando necesitemos comunicarnos con una aplicación echa en Java por poner un ejemplo?



Pues bien, la serialización viene al rescate, ya tenemos el escenario, nuestro problema está en la mesa. Tenemos nuestras clases, instancias concretas de esas clases y necesitamos almacenar y transmitir esa información. Aquí empezare a hacer hincapié que la serialización no es la panacea y que ahora debamos grabar así siempre en la Base de Datos o mandar de esa forma la información a otros sistemas, NO AHÍ COSAS BUENAS O MALAS, existen necesidades especificas y soluciones y está en nosotros saber identificar cuando debemos usar una pistola o un matamoscas.
Empezaremos con la serialización en formato binary, serializar es el proceso de crear un stream de bytes a partir de un objeto (una instancia concreta). Supongamos que tenemos una clase que se llama Empleado.


Si nosotros queremos serializar un objeto de esa clase necesitamos agregar el atributo [Serializable] a nuestra clase, si intentáramos serializar una clase que no tiene este atributo se generara una excepción.


Retomando lo que veníamos platicando si serializar es colocar nuestra instancia concreta en un stream de bytes ¿qué mas necesitamos?

1)Una instancia de nuestra clase Empleado

2)Un objeto de tipo stream que es donde almacenaremos nuestra instancia en un formato diferente, en este caso usaremos un objeto de tipo FileStream, esta clase nos proporciona nada menos que 15 constructores, usaremos lo necesario y eso es solo indicar el nombre del archivo que se generara y el modo en que estamos creando el objecto que es Create.

3)Requerimos por ultimo especificar la forma en que vamos a serializar,para serailizar en formato binary requerimos un objecto de tipo BinaryFormatter, este objecto nos permitira con el metodo “Serialize” serializar nuestra instancia concreta en el archivo stream que creamos, es decir lo vaciamos.


Hasta aquí hemos visto como convertir nuestra información de un objeto , ahora ¿qué sucede cuando necesitamos recuperar el objeto que serializamos?

1) Requerimos una variable del tipo de nuestra clase (NO una instancia).

2) Requerimos nuevamente un objeto de tipo stream para esta vez abrir el archivo que se genero y que contiene nuestra información serializada.

3) Requerimos nuevamente el objeto de tipo BinaryFormatter para esta vez con su metodo “Deserialize” deserealizar nuestra información y por ultimo hacer un cast de la información que hemos deserializado y setearlo a la variable que creamos en el paso 1


Comentarios :

I)BinaryFormatter es la mejor opción para serializar y deserializar objectos que solo seran interpretados por aplicaciones desarrolladas en .NETFrameWork
II)Existen otros "formateadores" XML , SOAP y Custom Serialization que son mas adecuados para ambientes que involucran sistemas operativos y aplicaciones ajenas al NetFrameWork e incluso a Windows y que nos permiten mayor flexibilidad.
III)Es una buena practica hacer nuestras clases serializables, aun cuando no tengamos claro si se usara, el dicho es "si ahi duda haslas serializables".

Los espacios de nombre utilizados fueron :
System.Runtime.Serialization.Formatters
System.Runtime.Serialization.Formatters.Binary
System.IO

Y regresando a la mecanica de plantear problemas dejo la pauta para la parte II con lo siguiente :
¿y si quiero que algunos miembros no sean serializables?
¿Como evitar problemas de compatibilidad entre versiones de mis clases?¿que pasa si agrego una nueva propiedad despues de que las clases ya estan siendo consumidas?
¿cual es la mejor practica para propiedades calculadas?