viernes, 26 de junio de 2015

El Libro del Día: Pro REST API Development with Node.js

El Libro del Día: 2015-06-26

Titulo: Pro REST API Development with Node.js
Autor: Fernando Doglio
Editorial: Apress
Nro Paginas: 191

Capítulos:
Chapter 1: Rest 101
Chapter 2: API Design Best Practices
Chapter 3: Node.js and REST
Chapter 4: Architecting a REST API
Chapter 5: Working with Modules
Chapter 6: Planning Your REST API
Chapter 7: Developing Your REST API
Chapter 8: Troubleshooting

Descarga:
Pro_REST_API_Development_with_Node.js

jueves, 25 de junio de 2015

Videos - Google I/O 2015

Videos del Google I/O 2015

Comparto con ustedes el evento mas importante de Google llamado I/O en su versión 2015.
Las sesiones son sobre Cloud Messaging, Android, Analytics, Games, Material Design, Polymer, FireBase, Play Services, Google Play, Android Wear, iOS, etc.

1. Keynote


2. Google Cloud Messaging 3.0


3. What's new in Android


4. What's New in Android Development Tools


5. Smarter monetization with AdMob and Analytics


6. The next generation mobile web


7. Growing games with Google


8. Material Now


9. Android Pay: The next generation of payments on Android


10. Polymer and modern web APIs: In production at Google scale


11. Smarter user acquisition with App Indexing, AdWords and Google Analytics


12. Project Tango - Mobile 3D tracking and perception


13. Developing Extraordinary Apps with Firebase


14. Designing for virtual reality


15. What's new in Google Play services


16. Improve your Android app's accessibility


17. Developers connecting the world through Google Play


18. Ubiquitous Computing with Google


19. Android Wear: Your app and the always-on screen


20. Developing with Google on iOS



El Libro del Día: HTML5, JavaScript, and jQuery

El Libro del Día: 2015-06-25

Titulo: HTML5, JavaScript, and jQuery. 24 Hour Trainer
Autor: Dane Cameron
Editorial: Wrox
Nro Paginas: 411

Capítulos:
PART I: HTML AND CSS
LESSON 1: INTRODUCTION TO HTML5
LESSON 2: BASIC HTML
LESSON 3: LISTS AND TABLES
LESSON 4: INTRODUCTION TO CSS
LESSON 5: STRUCTURING PAGES WITH CSS
LESSON 6: HTML FORMS
LESSON 7: SEMANTIC TAGS
LESSON 8: HTML5 VALIDATION
LESSON 9: DRAG AND DROP
LESSON 10: DYNAMIC ELEMENTS
PART II: DYNAMIC HTML5 WEB APPLICATIONS WITH JAVASCRIPT AND JQUERY
LESSON 11: JAVASCRIPT 95
LESSON 12: DEBUGGING
LESSON 13: FUNCTIONS
LESSON 14: OBJECTS
LESSON 15: JSON
LESSON 16: DOCUMENT OBJECT MODEL
LESSON 17: JQUERY SELECTION
LESSON 18: JQUERY TRAVERSAL AND MANIPULATION
LESSON 19: JQUERY EVENTS
LESSON 20: DATA ATTRIBUTES AND TEMPLATES
LESSON 21: JQUERY PLUGINS
PART III: HTML5 MULTIMEDIA
LESSON 22: HTML5 AUDIO
LESSON 23: HTML5 VIDEO
LESSON 24: CANVAS: PART I
LESSON 25: CANVAS: PART II
LESSON 26: CSS3: PART I
LESSON 27: CSS3: PART II
LESSON 28: CSS3 MEDIA QUERIES
PART IV: HTML5 APIS
LESSON 29: WEB SERVERS
LESSON 30: WEB STORAGE
LESSON 31: INDEXEDDB
LESSON 32: APPLICATION CACHE
LESSON 33: WEB WORKERS
LESSON 34: FILES
LESSON 35: AJAX
LESSON 36: PROMISES
PART V: MOBILE
LESSON 37: RESPONSIVE WEB DESIGN
LESSON 38: LOCATION API
LESSON 39: JQUERY MOBILE: PART I
LESSON 40: JQUERY MOBILE: PART II

Descarga:
HTML5_JavaScript_and_jQuery_24_Hour_Trainer

miércoles, 24 de junio de 2015

El Libro del Día: Beginning JavaScript

El Libro del Día: 2015-06-24

Titulo: Beginning JavaScript
Autor: Jeremy McPeak, Paul Wilton
Editorial: Wrox
Nro Paginas: 771

Capítulos:
Chapter 1: Introduction to JavaScript and the Web
Chapter 2: Data Types and Variables
Chapter 3: Decisions and Loops
Chapter 4: Functions and Scope
Chapter 5: JavaScript An Object Based Language
Chapter 6: String Manipulation
Chapter 7: Date, Time, and Timers
Chapter 8: Programming the Browser
Chapter 9: DOM Scripting
Chapter 10: Events
Chapter 11: HTML Forms: Interacting with the User
Chapter 12: JSON
Chapter 13: Data Storage
Chapter 14: Ajax
Chapter 15: HTML5 Media
Chapter 16: jQuery
Chapter 17: Other JavaScript Libraries
Chapter 18: Common Mistakes, Debugging, and Error Handling

Descarga:
Beginning_JavaScript

martes, 23 de junio de 2015

El Libro del Día: Beginning Google Glass Development

El Libro del Día: 2015-06-23

Titulo: Beginning Google Glass Development
Autor: Jeff Tang
Editorial: Apress
Nro Paginas: 358

Capítulos:
Chapter 1: Getting Started
Chapter 2: Hello, Glass Your First GDK App
Chapter 3: Glass User Interface
Chapter 4: Camera and Image Processing
Chapter 5: Video: Basics and Applications
Chapter 6: Voice and Audio
Chapter 7: Networking, Bluetooth, and Social
Chapter 8: Location, Map, and Sensors
Chapter 9: Graphics, Animation, and Games
Chapter 10: The Mirror API

Descarga:
Beginning_Google_Glass_Development

lunes, 22 de junio de 2015

El Libro del Día: Beginning JSON

El Libro del Día: 2015-06-22

Titulo: Beginning JSON
Autor: Ben Smith
Editorial: Apress
Nro Paginas: 353

Capítulos:
Chapter 1: JavaScript Basics
Chapter 2: Special Objects
Chapter 3: String Manipulation
Chapter 4: Introducing JSON
Chapter 5: Creating JSON
Chapter 6: Parsing JSON
Chapter 7: Persisting JSON: I
Chapter 8: Data Interchange
Chapter 9: X-Origin Resources
Chapter 10: Serving JSON
Chapter 11: Posting JSON
Chapter 12: Persisting JSON: II
Chapter 13: Working with Templates
Chapter 14: Putting It All Together

Descarga:
Beginning_JSON

viernes, 19 de junio de 2015

El Demo del Día: Aumentar Funcionalidad en una Aplicación WinForms usando Reflection (Sin Recompilar)

Aumentar Funcionalidad en una Aplicación WinForms usando Reflection (Sin Recompilar)

El Problema de la Actualización de Aplicaciones

Cada vez que se crea una Aplicación Windows se distribuye el ejecutable en las diferentes PCs de los usuarios que van a usar la aplicación.

Solución Actual al Problema de la Actualización de Aplicaciones

Si deseamos realizar cambios, sobre todo aumentar nueva funcionalidad, existen 2 soluciones comunes:

1. Recuperar los fuentes (código fuente), aumentar la funcionalidad, recompilar y volver a distribuir.

Problema: Si no se tiene los fuentes, porque muchas veces se compra solo el ejecutable (por dismunir costos) no se podría usar esta técnica.

2. Ejecutar desde el Módulo Principal los demás Módulos, es decir una aplicación preparada para ejecutar cualquier exe (los módulos)

Problema: No hay un control interno de las ventanas de los módulos que se ejecuten, por ejemplo que aparezcan dentro del MDI Principal, se puedan organizar y sobre todo el intercambio de datos.

Solución Propuesta al Problema de la Actualización de Aplicaciones

Construir un Sistema Principal que pueda ejecutar cualquier módulo, ya sea una aplicación o una librería, para eso usaremos Reflection.

Las 3 tareas a realizar desde el menú principal del sistema serían:
1. Ejecutar formularios (clases) desde cualquier ensamblado
2. Ejecutar procesos (exe) como por ejemplo utilitarios del sistema
3. Ejecutar métodos (funciones públicas) de cualquier clase de cualquier ensamblado

Con esta aproximación, para aumentar nueva funcionalidad solo basta hacer 2 cosas:
1. Aumentar en tablas (en nuestro caso un archivo de texto) las nuevas opciones del menú
2. Copiar el o los archivos exe (módulos de procesos, usables también independientemente) y archivos dll (módulos de librerías, usables solo por el módulo principal u otras aplicaciones).

Componentes del Demo

Este demo tiene los siguientes componentes (archivos):
1. Menus.txt: Archivo de texto con las opciones del menú principal a cargar.
2. SistemaPrincipal.exe: La aplicación principal (WinForms) que tiene un MDI con el código que permite cargar los menús y a través de este abrir cualquier formulario, ejecutar procesos y ejecutar métodos.
3. ModuloProcesos.exe: Una aplicación WinForms que contiene 2 formularios que van a aumentarse al Sistema Principal. También puede ejecutarse por si sola y muestra un formulario con dos opciones.
4. ModuloReportes.dll: Una librería conteniendo 2 formularios y una clase Rutinas con un método.

Crear la Aplicación Windows Forms con el Sistema Principal

Abrir Visual Studio y crear una aplicación Windows Forms en C# llamada "SistemaPrincipal", cambiarle de nombre al formulario por "frmPrincipal", configurar su propiedad IsMdiContainer en true y realizar el diseño similar a la figura mostrada:


Agregar 4 formularios al proyecto (configurar su propiedad BackColor en Red), con los siguientes nombres:
- frmConProdCat.cs: Propiedad Text en "Consulta de Productos por Categoria"
- frmConProdProv.cs: Propiedad Text en "Consulta de Productos Proveedor"
- frmManCliente.cs: Propiedad Text en "Mantenimiento de Clientes"
- frmManEmpleado.cs: Propiedad Text en "Mantenimiento de Empleados"

Crear una Clase Entidad de Negocio para el Menú

Agregar una clase al proyecto llamada: "beMenu" y escribir el siguiente código:

using System;
namespace SistemaPrincipal
{
    public class beMenu
    {
        public string IdMenu { get; set; }
        public string Titulo { get; set; }
        public string Ensamblado { get; set; }
        public string Accion { get; set; }
        public string IdPadre { get; set; }
    }
}

Crear una Clase Agente de Servicio para el Menú

Agregar una clase al proyecto llamada: "saMenu" y escribir el siguiente código:

using System;
using System.Text;
using System.IO;
using System.Collections.Generic;
namespace SistemaPrincipal
{
    public class saMenu
    {
        public List<beMenu> Listar(string NombreArchivo)
        {
            List<beMenu> lbeMenu = null;
            if (File.Exists(NombreArchivo))
            {
                using (StreamReader sr = new StreamReader(NombreArchivo, Encoding.Default))
                {
                    string[] menu;
                    lbeMenu = new List<beMenu>();
                    beMenu obeMenu;
                    while (!sr.EndOfStream)
                    {
                        menu = sr.ReadLine().Split(',');
                        obeMenu = new beMenu();
                        obeMenu.IdMenu = menu[0];
                        obeMenu.Titulo = menu[1];
                        obeMenu.Ensamblado = menu[2];
                        obeMenu.Accion = menu[3];
                        obeMenu.IdPadre = menu[4];
                        lbeMenu.Add(obeMenu);
                    }
                }
            }
            return (lbeMenu);
        }
    }
}

Nota: Para los que no conocen la terminología distribuida, si la clase es de datos es da: DataAccess, pero si trabajamos con recursos que no son bases de datos, como archivos de texto, la clase es sa: ServiceAgents (Agentes de Servicio).

Crear una Clase Regla de Negocio para el Menú

Agregar una clase al proyecto llamada: "brMenu" y escribir el siguiente código:

using System;
using System.Collections.Generic;
namespace SistemaPrincipal
{
    public class brMenu
    {
        public List<beMenu> Listar()
        {
            List<beMenu> lbeMenu = null;
            saMenu osaMenu = new saMenu();
            lbeMenu = osaMenu.Listar("Menus.txt");
            return (lbeMenu);
        }
    }
}

Escribir Código para el Formulario frmPrincipal

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using System.IO;

namespace SistemaPrincipal
{
    public partial class frmPrincipal : Form
    {
        List<beMenu> lbeMenu;

        public frmPrincipal()
        {
            InitializeComponent();
        }

        private void llenarMenus(object sender, EventArgs e)
        {
            brMenu obrMenu = new brMenu();
            lbeMenu = obrMenu.Listar();
            List<beMenu> lbeRaiz = lbeMenu.FindAll(x=>x.IdPadre.Equals("0"));
            ToolStripMenuItem mnuRaiz;
            foreach(beMenu obeMenu in lbeRaiz)
            {
                mnuRaiz=new ToolStripMenuItem(obeMenu.Titulo);
                mnuRaiz.Tag = String.Format("{0}|{1}", obeMenu.Accion, obeMenu.Ensamblado);
                if (!obeMenu.Accion.Equals("")) mnuRaiz.Click += new EventHandler(ejecutarAccion);
                mnuPrincipal.Items.Add(mnuRaiz);
                crearSubMenu(obeMenu, mnuRaiz);
            }
        }

        private void crearSubMenu(beMenu obeMenuPadre,ToolStripMenuItem mnuPadre)
        {
            List<beMenu> lbeMenuHijos =
            lbeMenu.FindAll(x=>x.IdPadre.Equals(obeMenuPadre.IdMenu));
            ToolStripMenuItem mnuHijo;
            foreach (beMenu obeMenuHijo in lbeMenuHijos)
            {
                mnuHijo = new ToolStripMenuItem(obeMenuHijo.Titulo);
                mnuHijo.Tag = String.Format("{0}|{1}", obeMenuHijo.Accion,
                obeMenuHijo.Ensamblado);
                if (!obeMenuHijo.Accion.Equals("")) mnuHijo.Click +=
                new EventHandler(ejecutarAccion);
                mnuPadre.DropDownItems.Add(mnuHijo);
                crearSubMenu(obeMenuHijo, mnuHijo);
            }
        }

        private void ejecutarAccion(object sender,EventArgs e)
        {
            ToolStripMenuItem mnu = (ToolStripMenuItem)sender;
            string[] opciones = mnu.Tag.ToString().Split('|');
            string accion = opciones[0];
            string nombreEnsamblado = opciones[1];
            if (accion.StartsWith("frm"))
            {
                Assembly ensamblado = Assembly.LoadFrom(nombreEnsamblado);
                if (ensamblado != null)
                {
                    Type tipo = ensamblado.GetType(String.Format("{0}.{1}",
                    Path.GetFileNameWithoutExtension(nombreEnsamblado),accion));
                    if (tipo != null)
                    {
                        object obj = Activator.CreateInstance(tipo);
                        if (obj != null)
                        {
                            Form frm = (Form)obj;
                            frm.MdiParent = this;
                            frm.Show();
                        }
                    }
                }
            }
            else
            {
                if (accion.EndsWith(".exe"))
                {
                    Process.Start(accion);
                }
                else
                {
                    opciones = accion.Split('.');
                    accion = opciones[0];
                    string clase = opciones[1];
                    if (nombreEnsamblado.Equals("SistemaPrincipal.exe") &&
                    clase.Equals("frmPrincipal"))
                    {
                        MethodInfo mi = this.GetType().GetMethod(accion);
                        var rpta = mi.Invoke(this, null);
                        if (rpta != null) MessageBox.Show(rpta.ToString());
                    }
                    else
                    {
                        Assembly ensamblado = Assembly.LoadFrom(nombreEnsamblado);
                        if (ensamblado != null)
                        {
                            Type tipo = ensamblado.GetType(String.Format("{0}.{1}",
                            Path.GetFileNameWithoutExtension(nombreEnsamblado), clase));
                            if (tipo != null)
                            {
                                object obj = Activator.CreateInstance(tipo);
                                if (obj != null)
                                {
                                    MethodInfo mi = tipo.GetMethod(accion);
                                    if (mi != null)
                                    {
                                        var rpta = mi.Invoke(obj, null);
                                        if (rpta != null) MessageBox.Show(rpta.ToString());
                                    }
                                }
                            }
                        }

                    }
                }
            }
        }

        public void salirApp()
        {
            this.Close();
        }
    }
}

Nota: Asociar al evento "Load" del formulario "frmPrincipal" el método: "llenarMenus", el cual lista las opciones de la raíz o primer nivel, luego la función "crearSubMenu" recursivamente llena los demás niveles.

Crear el Archivo de Texto con las opciones del menu principal

Antes de crear el archivo de texto, hay que grabar y compilar la aplicación y luego ir a la carpeta "bin", "debug" y crear el archivo de texto "Menus.txt" similar a la figura mostrada:


Primera Prueba de la Aplicación Sistema Principal

Si se ejecuta la aplicación se mostrará el MDI con los menús cargados y si abrimos los formularios se mostrará similar a la siguiente figura:


Nota: La primera prueba consiste en mostrar solo las opciones que estan dentro del propio sistema (sin integración).

Crear otra Aplicación Windows Forms con el Módulo de Procesos

Crear una nueva aplicación Windows Forms en C# llamada "ModuloProcesos", cambiarle de nombre al formulario por "frmPrincipal" y configurar su propiedad BackColor en Green, y realizar el diseño similar a la figura mostrada:


Agregar 2 formularios al proyecto (configurar su propiedad BackColor en Green), con los siguientes nombres:
- frmNuevaOrden.cs: Propiedad Text en "Modulo de Procesos - Nueva Orden"
- frmNuevaFactura.cs: Propiedad Text en "Modulo de Procesos - Nueva Factura"

Escribir el siguiente código en el formulario "frmPrincipal":

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ModuloProcesos
{
    public partial class frmPrincipal : Form
    {
        public frmPrincipal()
        {
            InitializeComponent();
        }

        private void btnNuevaOrden_Click(object sender, EventArgs e)
        {
            frmNuevaOrden frm = new frmNuevaOrden();
            frm.WindowState = FormWindowState.Maximized;
            frm.ShowDialog();
        }

        private void btnNuevaFactura_Click(object sender, EventArgs e)
        {
            frmNuevaFactura frm = new frmNuevaFactura();
            frm.WindowState = FormWindowState.Maximized;
            frm.ShowDialog();
        }

        private void btnSalirApp_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

Grabar y probar la aplicación ModuloProcesos.

Crear una Librería de Clases con el Módulo de Reportes

Crear una nueva Librería de Clases en C# llamada "ModuloReportes", cambiarle de nombre a la clase por "Rutinas.cs" y escribir el siguiente código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ModuloReportes
{
    public class Rutinas
    {
        public string procesar()
        {
            return "Procesando";
        }
    }
}

Hacer referencias a 2 librerías: System.Drawing.dll y System.Windows.Forms.dll

Agregar 2 formularios al proyecto (configurar su propiedad BackColor en Blue), con los siguientes nombres:
- frmRepCliente.cs: Propiedad Text en "Modulo de Reportes - Clientes"
- frmRepOrden.cs: Propiedad Text en "Modulo de Reportes - Ordenes"

Grabar y compilar la librería.

Nota: Esta No se puede ejecutar porque es una librería de clases, solo funciona desde una aplicación que la llame.

Segunda Prueba de la Aplicación Sistema Principal

Recuperar la aplicación "SistemaPrincipal", sacar una copia al archivo "Menus.txt" (carpeta bin, debug) y aumentar mas opciones al archivo, tal como se muestra en la siguiente figura:


Copiar los archivos ModuloProcesos.exe y ModuloReportes.dll hacia la carpeta bin, debug donde se encuentra la aplicación SistemaPrincipal.exe y el archivo Menus.txt.

Ejecutar nuevamnete la aplicación y se mostrará el MDI con los menús cargados (los cuales han aumentado) y si abrimos los formularios se mostrará similar a la siguiente figura:


Observe que cada color diferencia el ensamblado donde se encuentra el formulario:
- Rojo: Formularios de la Aplicación Sistema Principal
- Verde: Formularios de la Aplicación Modulo Procesos
- Azul: Formularios de la Librería de Clases Modulo Reportes

También observe que al seleccionar "Reportes", "Graficos", "Estadistica" se ejecuta un método externo "procesar" encontrado en la Librería de Clases "ModuloReportes.dll" y cuando se elige la opción "Salir" se ejecuta el método "salirApp" ubicado en la misma clase del formulario MDI.

Comentario Final

En este post, hemos visto como aumentar funcionalidad a una Aplicación Windows sin Recompilar la Aplicación usando Reflection. Los menús se han cargado usando un archivo de texto, pero en vez de este puede ser una tabla de una base de datos.

Si bien es cierto, el uso intensivo de Reflection (sobre todo llamadas en bucles), no es recomendable, existen muchos casos como en este, que nos sirven de gran ayuda.

Muchos desarrolladores, desconecen la importancia y la gran cantidad de usos que se pueden dar a Reflection, pero en este Blog siempre estamos dando a conocer su importancia para darle "inteligencia" a tus soluciones.

Video del Demo

Aquí les dejo, un video parecido al Demo posteado, con la diferencia que la aplicación SistemaPrincipal se llama Demo12, la aplicación ModuloProcesos se llama Demo13 y la librería ModuloReportes se llama Demo14, pero igual les puede servir de guia.


Descarga del Código

2015_06_19_DemoDia_SistemaPrincipal

El Libro del Día: Node.js Design Patterns

El Libro del Día: 2015-06-19

Titulo: Node.js Design Patterns
Autor: Mario Casciaro
Editorial: Packt
Nro Paginas: 454

Capítulos:
Chapter 1: Node.js Design Fundamentals
Chapter 2: Asynchronous Control Flow Patterns
Chapter 3: Coding with Streams
Chapter 4: Design Patterns
Chapter 5: Wiring Modules
Chapter 6: Recipes
Chapter 7: Scalability and Architectural Patterns
Chapter 8: Messaging and Integration Patterns

Descarga:
Node.js_Design_Patterns

jueves, 18 de junio de 2015

El Libro del Día: Practical Node.js

El Libro del Día: 2015-06-18

Titulo: Practical Node.js
Autor: Azat Mardan
Editorial: Apress
Nro Paginas: 288

Capítulos:
Chapter 1: Setting up Node.js and Other Essentials
Chapter 2: Using Express.js 4 to Create Node.js Web Apps
Chapter 3: TDD and BDD for Node.js with Mocha
Chapter 4: Template Engines: Jade and Handlebars
Chapter 5: Persistence with MongoDB and Mongoskin
Chapter 6: Using Sessions and OAuth to Authorize and Authenticate Users in Node.js Apps
Chapter 7: Boosting Your Node.js Data with the Mongoose ORM Library
Chapter 8: Building Node.js REST API Servers with Express.js and Hapi
Chapter 9: Real-Time Apps with WebSocket, Socket.IO, and DerbyJS
Chapter 10: Getting Node.js Apps Production Ready
Chapter 11: Deploying Node.js Apps
Chapter 12: Publishing Node.js Modules and Contributing to Open Source

Descarga:
Practical_Node.js

miércoles, 17 de junio de 2015

Entrenamiento - .NET Developer (The Best Practices for Performance)

.NET Developer (The Best Practices for Performance)

Comparto el contenido del nuevo Programa de Capacitación que estoy brindando para todos los interesados en profundizar sus conocimientos en la plataforma Microsoft .NET

Modulo 1: Windows Developer (72 horas en 3 meses)
Fundamentals 
Curso 01: .NET Framework (18 horas)
Curso 02: ADO .NET (18 horas)
Windows Applications 
Curso 03: WinForms  (18 horas)
Curso 04: WPF  (18 horas)

Modulo 2: Web Developer (72 horas en 3 meses)
Back End 
Curso 05: ASP.NET MVC (18 horas)
Curso 06: Servicios (WCF y Web API) (18 horas)
Front End
Curso 07: JavaScript (DOM, jQuery, AJAX) (18 horas)
Curso 08: HTML5 (APIs) (18 horas)

Modulo 3: Mobile Developer (72 horas en 3 meses)
Web Mobile 
Curso 09: Responsive Web Designe (CSS3+HTML5+MVC) (18 horas)
Curso 10: jQuery Mobile (18 horas)
Native Apps
Curso 11: Xamarin Forms iOS (18 horas)
Curso 12: Xamarin Forms Android (18 horas)

Hay 2 tipos de cursos:
- Cerrados para Empresas (Horarios de Lunes a Viernes en horarios a elegir)
- Libres para cualquier participante (Horarios: Sabados en la Tarde o Domingos en las Mañanas)

Ambos son 6 horas por semana, es decir 24 horas por mes, 3 meses por cada Módulo.

Los interesados enviar un mail a: Luis.duenash@gmail.com indicando lo siguiente:
- Nombre (curso Libre) o Empresa (curso Cerrado)
- Horario Seleccionado
- Fecha Inicio deseada (para Empresa)

En el mercado hay varias alternativas de capacitación en .NET, pero ninguna esta orientada a las Verdaderas Buenas Prácticas de Programación, sobre todo a la performance. En el programa se ve desde el inicio hasta el final como optimizar memoria y procesador.

El Libro del Día: Professional Node.js

El Libro del Día: 2015-06-17

Titulo: Professional Node.js
Autor: Pedro Teixeira
Editorial: Wrox
Nro Paginas: 412

Capítulos:
PART I INTRODUCTION AND SETUP
CHAPTER 1 Installing Node
CHAPTER 2 Introducing Node
PART II NODE CORE API BASICS
CHAPTER 3 Loading Modules
CHAPTER 4 Using Buffers to Manipulate, Encode, and Decode Binary Data
CHAPTER 5 Using the Event Emitter Pattern to Simplify Event Binding
CHAPTER 6 Scheduling the Execution of Functions Using Timers
PART III FILES, PROCESSES, STREAMS, AND NETWORKING
CHAPTER 7 Querying, Reading from, and Writing to Files
CHAPTER 8 Creating and Controlling External Processes
CHAPTER 9 Reading and Writing Streams of Data
CHAPTER 10 Building TCP Servers
CHAPTER 11 Building HTTP Servers
CHAPTER 12 Building a TCP Client
CHAPTER 13 Making HTTP Requests
CHAPTER 14 Using Datagrams (UDP)
CHAPTER 15 Securing Your TCP Server with TLS/SSL
CHAPTER 16 Securing Your HTTP Server with HTTPS
PART IV BUILDING AND DEBUGGING MODULES AND APPLICATIONS
CHAPTER 17 Testing Modules and Applications
CHAPTER 18 Debugging Modules and Applications
CHAPTER 19 Controlling the Callback Flow
PART V BUILDING WEB APPLICATIONS
CHAPTER 20 Building and Using HTTP Middleware
CHAPTER 21 Making a Web Application Using Express.js
CHAPTER 22 Making Universal Real-Time Web Applications Using Socket.IO
PART VI CONNECTING TO DATABASES
CHAPTER 23 Connecting to MySQL Using node-mysql
CHAPTER 24 Connecting to CouchDB Using Nano
CHAPTER 25 Connecting to MongoDB Using Mongoose

Descarga:
Professional_Node.js

martes, 16 de junio de 2015

El Libro del Día: Beginning Node.js

El Libro del Día: 2015-06-16

Titulo: Beginning Node.js
Autor: Basarat Ali Syed
Editorial: Apress
Nro Paginas: 297

Capítulos:
Chapter 1: Setting Up for Node.js Development
Chapter 2: Understanding Node.js
Chapter 3: Core Node.js
Chapter 4: Node.js Packages
Chapter 5: Events and Streams
Chapter 6: Getting Started with HTTP
Chapter 7: Introducing Express
Chapter 8: Persisting Data
Chapter 9: Front-End Basics
Chapter 10: Simplifying Callbacks
Chapter 11: Debugging
Chapter 12: Testing
Chapter 13: Deployment and Scalability

Descarga:
Beginning_Node.js

viernes, 12 de junio de 2015

Videos - IoTaConf Octubre 2014

Videos del IoTaConf Octubre 2014

El futuro de la computación es el Internet de las Cosas (IoT), y en este post les comparto los videos de uno de los eventos mas importantes a nivel mundial sobre este tema.

1. Olivier Bloch: Using Microsoft tools and platforms to build the IoT



2. Michael Koster, ARM: Design Patterns for an Internet of Things


3. Todd Montgomery, Kaazing: IoT Connectivity, Standards & Architecture


4. Wayne Piekarski, Google: Android Wear


5. Ravi Kurani, Sutro: 50 Billion Devices and the Next Billion Consumers


6. Bo Huang, SenseEarth: Real world maps in first person with Oculus Rift


7. Alex Lebrurn, Wit.AI: Speech Interfaces for the Internet of Things


8. Abhishek Sanwal: IOT Landscape, Evolution & Marturity Models. Rework the Internet


9. Andy Carle, Marvell: Mind the Gap. JavaScript for IoT, from Concept to Production


10. Kevin Hoyt, Kaazing: IoT and the New Web


11. Oliver Hutaff, Electric Imp: The True Value of the Internet of Things


12. Alfred Lui, Seer Labs: Re-orientating­ UX Design for the Internet of Things


13. Rikard Strid, Clayster: XMPP - Normalize Internet Of Things



El Libro del Día: Rethinking the Internet of Things

El Libro del Día: 2015-06-12

Titulo: Rethinking the Internet of Things
Autor: Francis daCosta
Editorial: Apress
Nro Paginas: 185

Capítulos:
Chapter 1: It’s Different Out Here
Chapter 2: Anatomy of the Internet of Things
Chapter 3: On the Edge
Chapter 4: Building a Web of Things
Chapter 5: Small Data, Big Data, and Human Interaction
Chapter 6: Architecture for the Frontier
Chapter 7: Examples and Applications
Chapter 8: Pathways to the Internet of Things

Descarga:
Rethinking_the_Internet_of_Things

lunes, 8 de junio de 2015

El Libro del Día: Pro Grunt.js

El Libro del Día: 2015-06-08

Titulo: Pro Grunt.js
Autor: James Cryer
Editorial: Apress
Nro Paginas: 165

Capítulos:
Chapter 1: Introducing Grunt
Chapter 2: How to Use Grunt in Your Project
Chapter 3: Using Grunt with HTML and CSS
Chapter 4: Using Grunt with JavaScript
Chapter 5: Using Grunt with Images, SVG, and Icons
Chapter 6: Using Grunt for Testing and Local Development
Chapter 7: Optimizing Your Grunt Workflow

Descarga:
Pro_Grunt.js

viernes, 5 de junio de 2015

El Libro del Día: Practical .NET 2.0 Networking Projects

El Libro del Día: 2015-06-05

Titulo: Practical .NET 2.0 Networking Projects
Autor: Wei-Meng Lee
Editorial: Apress
Nro Paginas: 291

Capítulos:
CHAPTER 1 Sockets Programming
CHAPTER 2 Serial Communications
CHAPTER 3 Incorporating Fingerprint Recognition into Your .NET Application
CHAPTER 4 Infrared Programming
CHAPTER 5 Fun with RFID
CHAPTER 6 Interfacing with External Devices

Descarga:
Practical_.NET_2.0_Networking_Projects

jueves, 4 de junio de 2015

El Demo del Día: Performace entre Serializadores .NET

Performace entre Serializadores .NET

El Problema de la Performance

Uno de los problemas principales de los Sistemas Informáticos Modernos es la Performance, sea Windows o Web la Aplicación, con el crecimiento del uso (aumento de usuarios) dentro (Intranet) y fuera de la empresa (Internet) las aplicaciones cada vez son mas lentas.

Esta lentitud es tratada de resolver aumentando Hardware como mas Servidores, mas Memorias, mas CPUs, mas Ancho de Banda, etc. Todo menos hacer una reingeniería del desarrollo que es la principal causa, es decir el problema es la forma cómo se programa (Software) donde lo común es que se realizan muchas conexiones al Servidor de Base de Datos, se usan estructuras de datos pesadas (por ejemplo en .NET los DataSets), se hacen bucles expensivos, etc.

Solución al Problema de la Performance

Aprender las Buenas Prácticas de Programación que permitan consumir la menor cantidad de memoria con el menor tiempo de procesamiento, para lo cual hay diferentes las cuales compartiremos a partir de hoy, empezando por una Comparación de Serializadores para elegir el mejor.

Definición de Serialización

Según Wikipedia, la Serialización (o Marshalling en inglés) es el proceso de codificación de un objeto en un medio de almacenamiento (como puede ser un archivo, o un buffer de memoria) con el fin de transmitirlo a través de una conexión en red como una serie de bytes o en un formato humanamente más legible como XML o JSON, entre otros.

La serie de bytes o el formato pueden ser usados para crear un nuevo objeto que es idéntico en todo al original, incluido su estado interno (por tanto, el nuevo objeto es un clon del original).

La Serialización es un mecanismo ampliamente usado para transportar objetos a través de una red, para hacer persistente un objeto en un archivo o base de datos, o para distribuir objetos idénticos a varias aplicaciones o localizaciones.

Importancia de elegir un Serializador

Es necesario saber elegir adecuadamente un Serializador, ya que cada vez que enviamos datos entre dos procesos se usa la serialización. 

A continuación listamos los Serializadores .NET junto con los tipos de aplicaciones o tecnologías distribuidas que las usan por defecto:

- Serializador Binario: Usado en Sockets y .NET Remoting (dll)
- Serializador SOAP: Usado por Servicios Web XML (asmx)
- Serializador XML: Usado por los Servicios WCF (svc y dll)
- Serializador JSON: Usado en Web API
- Serializador Personalizado: Hay que crearlo uno mismo.

La importancia de seleccionar bien el Serializador es que este es el factor principal de performance al momento de usar un Servicio o una Aplicación Distibuida, es decir, depende de este el tiempo de serialización deserealización y sobre todo el formato y el tamaño de los datos que se pasan por la red.

En este post, comprobaremos cual es el mejor, sin embargo la mayoría siempre usa el peor y después quiere que sus Servicios sean rápidos, es decir, quieren una cosa (Performance) pero hacen otra (Estándar).

Crear una Aplicación Windows Forms en C#

Abrir Visual Studio y crear una aplicación Windows Forms en C# llamada "Comparacion_Serializacion", cambiarle de nombre al formulario por "frmListaProductos" y realizar el diseño similar a la figura mostrada:


Nota: En el diseño hay un DataGridView llamado "dgvProducto", un menú contextual llamado "mnuContextual" con 6 opciones: mnuCargarDatos, mnuBinario, mnuSOAP, mnuXML, mnuJSON y mnuPersonalizado.

Crear el Procedimiento Almacenado en SQL Server

Crear el Procedimiento llamado "uspProductsListar" en SQL Server:

Create Procedure uspProductsListar
As
Select ProductID, ProductName, SupplierID, 
CategoryID,UnitPrice, UnitsInStock
From Products

Crear la Clase Entidad del Negocio

Agregar una clase al proyecto llamada: "beProducto" y escribir el siguiente código:

using System;
using System.Runtime.Serialization;

namespace Comparacion_Serializacion
{
    //[Serializable]
    //[DataContract]
    public class beProducto
    {
        //[DataMember]
        public int IdProducto { get; set; }
        //[DataMember]        
        public string Nombre { get; set; }
        //[DataMember]
        public int IdProveedor { get; set; }
        //[DataMember]
        public int IdCategoria { get; set; }
        //[DataMember]
        public decimal PrecioUnitario { get; set; }
        //[DataMember]
        public short Stock { get; set; }
    }
}

Nota: Los atributos de serialización (Serializable, DataContract y DataMember) han sido comentados inicialmente para ver que sucede cuando se intenta serializar con cada técnica.

Crear la Clase de Acceso a Datos

Agregar una clase al proyecto llamada: "daProducto" y escribir el siguiente código:

using System;
using System.Collections.Generic; //List
using System.Data; //CommandType, CommandBehavior
using System.Data.SqlClient; //SqlConnection, SqlCommand, SqlDataReader

namespace Comparacion_Serializacion
{
    public class daProducto
    {
        public List<beProducto> listar(SqlConnection con)
        {
            List<beProducto> lbeProducto = null;

            SqlCommand cmd = new SqlCommand("uspProductsListar", con);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlDataReader drd = cmd.ExecuteReader(CommandBehavior.SingleResult);
            if (drd != null)
            {
                lbeProducto = new List<beProducto>();
                int posIdProducto = drd.GetOrdinal("ProductID");
                int posNombre = drd.GetOrdinal("ProductName");
                int posIdProveedor = drd.GetOrdinal("SupplierID");
                int posIdCategoria = drd.GetOrdinal("CategoryID");
                int posPrecioUnitario = drd.GetOrdinal("UnitPrice");
                int posStock = drd.GetOrdinal("UnitsInStock");
                beProducto obeProducto;
                while (drd.Read())
                {
                    obeProducto = new beProducto();
                    obeProducto.IdProducto = drd.GetInt32(posIdProducto);
                    obeProducto.Nombre = drd.GetString(posNombre);
                    obeProducto.IdProveedor = drd.GetInt32(posIdProveedor);
                    obeProducto.IdCategoria = drd.GetInt32(posIdCategoria);
                    obeProducto.PrecioUnitario = drd.GetDecimal(posPrecioUnitario);
                    obeProducto.Stock = drd.GetInt16(posStock);
                    lbeProducto.Add(obeProducto);
                }
                drd.Close();
            }

            return (lbeProducto);
        }
    }
}

Crear la Clase de Reglas del Negocio

Agregar una clase al proyecto llamada: "brProducto" y escribir el siguiente código:

using System;
using System.Configuration; //ConfigurationManager
using System.Data.SqlClient; //SqlConnection
using System.Collections.Generic; //List

namespace Comparacion_Serializacion
{
    public class brProducto
    {
        public string CadenaConexion { get; set; }
        private string archivoLog;

        public brProducto()
        {
            CadenaConexion = 
                ConfigurationManager.ConnectionStrings["conNW"].ConnectionString;
        }

        public List<beProducto> listar()
        {
            List<beProducto> lbeProducto = null;
            using (SqlConnection con = new SqlConnection(CadenaConexion))
            {
                try
                {
                    con.Open();
                    daProducto odaProducto = new daProducto();
                    lbeProducto = odaProducto.listar(con);
                }
                catch (SqlException ex)
                {
                    //grabarLog(ex);
                }
                catch (Exception ex)
                {
                    //grabarLog(ex);
                }
            } //con.Close(); con.Dispose();
            return (lbeProducto);
        }
    }
}

Nota: Para usar la clase "ConfigurationManager", primero hay que hacer referencia a la librería "System.Configuration.dll"

Crear una Clase para la Serialización Personalizada de Strings

Agregar una clase al proyecto llamada: "CustomSerializer" y escribir el siguiente código:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.IO;

namespace Comparacion_Serializacion
{
    public class CustomSerializer
    {
        public static void Serializar<T>(List<T> lista, string archivo, char separadorCampo, 
        char separadorRegistro)
        {
            StringBuilder sb = new StringBuilder();
            PropertyInfo[] propiedades = lista[0].GetType().GetProperties();
            for (int i = 0; i < propiedades.Length; i++)
            {
                sb.Append(propiedades[i].Name);
                if (i < propiedades.Length - 1) sb.Append(separadorCampo);
            }
            sb.Append(separadorRegistro);
            for (int j = 0; j < lista.Count; j++)
            {
                propiedades = lista[j].GetType().GetProperties();
                for (int i = 0; i < propiedades.Length; i++)
                {
                    if (propiedades[i].GetValue(lista[j], null) != null) 
                    sb.Append(propiedades[i].GetValue(lista[j], null).ToString());
                    else sb.Append("");
                    if (i < propiedades.Length - 1) sb.Append(separadorCampo);
                }
                if (j < lista.Count - 1) sb.Append(separadorRegistro);
            }
            File.WriteAllText(archivo,sb.ToString());
        }

        public static List<T> Deserializar<T>(string archivo, char separadorCampo, 
        char separadorRegistro)
        {
            List<T> lista = new List<T>();
            if (File.Exists(archivo))
            {
                string contenido = File.ReadAllText(archivo);
                string[] registros = contenido.Split(separadorRegistro);
                string[] campos;
                string[] cabecera = registros[0].Split(separadorCampo);
                string registro;
                Type tipoObj;
                T obj;
                dynamic valor;
                Type tipoCampo;
                for (int i = 1; i < registros.Length; i++)
                {
                    registro = registros[i];
                    tipoObj = typeof(T);
                    obj = (T)Activator.CreateInstance(tipoObj);
                    campos = registro.Split(separadorCampo);
                    for (int j = 0; j < campos.Length; j++)
                    {
                        tipoCampo = obj.GetType().GetProperty(cabecera[j]).PropertyType;
                        valor = Convert.ChangeType(campos[j],tipoCampo);
                        obj.GetType().GetProperty(cabecera[j]).SetValue(obj, valor);
                    }
                    lista.Add(obj);
                }
            }
            return (lista);
        }
    }
}

Nota: Para crear mi propio Serializador uso Reflection y Listas Genéricas. 
Una de las claves para hacer la Deserealización es crear una instancia del objeto dinámicamente con Activator.CreateInstance y luego escribir el valor desde la cadena al objeto para lo cual uso Convert.ChangeType.

Escribir el Código del Formulario frmListaProducto

Antes de escribir el código de los Serializadores hay que hacer las siguientes Referencias:
- System.Runtime.Serialization.Formatters.Soap.dll para la Serialización SOAP
- System.Runtime.Serialization para la Serialización JSON

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO; //FileStream
using System.Linq; //ToList
using System.Diagnostics; //Stopwatch
using System.Runtime.Serialization.Formatters.Binary; //BinaryFormatter
using System.Runtime.Serialization.Formatters.Soap; //SoapFormatter
using System.Xml.Serialization; //XmlSerializer
using System.Runtime.Serialization.Json; //DataContractJsonSerializer

namespace Comparacion_Serializacion
{
    public partial class frmListaProducto : Form
    {
        private List<beProducto> lbeProducto;

        public frmListaProducto()
        {
            InitializeComponent();
        }

        private void cargarDatos(object sender, EventArgs e)
        {
            brProducto obrProducto = new brProducto();
            lbeProducto = obrProducto.listar();
            dgvProducto.DataSource = lbeProducto;
        }

        private void medirTiempo(Action metodo)
        {
            Stopwatch cronometro = new Stopwatch();
            cronometro.Start();
            metodo();
            MessageBox.Show(String.Format("Tiempo de Duración: {0:n0} msg", 
            cronometro.Elapsed.TotalMilliseconds));
            cronometro.Stop();
        }

        private void serializarBinario()
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (FileStream fs = new FileStream("Binario.txt",
                FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                bf.Serialize(fs, lbeProducto);
            }
        }

        private void deserializarBinario()
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (FileStream fs = new FileStream("Binario.txt",
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                lbeProducto=(List<beProducto>)bf.Deserialize(fs);
            }
        }

        private void serializarSOAP()
        {
            SoapFormatter sf = new SoapFormatter();
            using (FileStream fs = new FileStream("SOAP.txt",
                FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                sf.Serialize(fs, lbeProducto.ToArray());
            }
        }

        private void deserializarSOAP()
        {
            SoapFormatter sf = new SoapFormatter();
            using (FileStream fs = new FileStream("SOAP.txt",
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                lbeProducto=((beProducto[])sf.Deserialize(fs)).ToList();
            }
        }

        private void serializarXML()
        {
            XmlSerializer xs = new XmlSerializer(typeof(List<beProducto>));
            using (FileStream fs = new FileStream("XML.txt",
                FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                xs.Serialize(fs, lbeProducto);
            }
        }

        private void deserializarXML()
        {
            XmlSerializer xs = new XmlSerializer(typeof(List<beProducto>));
            using (FileStream fs = new FileStream("XML.txt",
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                lbeProducto = (List<beProducto>)xs.Deserialize(fs);
            }
        }

        private void serializarJSON()
        {
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(List<beProducto>));
            using (FileStream fs = new FileStream("JSON.txt",
                FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                js.WriteObject(fs, lbeProducto);
            }
        }

        private void deserializarJSON()
        {
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(List<beProducto>));
            using (FileStream fs = new FileStream("JSON.txt",
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                lbeProducto=(List<beProducto>)js.ReadObject(fs);
            }
        }

        private void serializarString()
        {
            CustomSerializer.Serializar(lbeProducto, "Strings.txt", ',', '|');
        }

        private void deserializarString()
        {
            lbeProducto=CustomSerializer.Deserializar<beProducto>("Strings.txt", ',', '|');
        }

        private void mnuSerializarBinario_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarBinario);
        }

        private void mnuDeserializarBinario_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarBinario);
            dgvProducto.DataSource = lbeProducto;
        }

        private void mnuSerializarSOAP_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarSOAP);
        }

        private void mnuDeserializarSOAP_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarSOAP);
            dgvProducto.DataSource = lbeProducto;
        }

        private void mnuSerializarXML_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarXML);
        }

        private void mnuDeserializarXML_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarXML);
            dgvProducto.DataSource = lbeProducto;
        }

        private void mnuSerealizarJSON_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarJSON);
        }

        private void mnuDeserealizarJSON_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarJSON);
            dgvProducto.DataSource = lbeProducto;
        }

        private void mnuSerializarPersonalizado_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarString);
        }

        private void mnuDeserializarPersonalizado_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarString);
            dgvProducto.DataSource = lbeProducto;
        }
    }
}

Nota: Todos las funciones manejadoras de eventos llaman a la función "medirTiempo" para ejecutar la Serialización y Deserealización.

Modificar el Archivo de Configuración

Abrir el archivo app.Config y aumentar la cadena de conexión:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="conNW" providerName="SQLServer"
      connectionString="uid=UsuarioNW;pwd=123456;
      server=DSOFT\Sqlexpress;database=Northwind"/>
  </connectionStrings>
  <startup> 
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

Ejecutar y Probar la Aplicación Windows Forms

Grabar la aplicación y pulsar F5 para ejecutarla. Aparecerá una ventana similar a la siguiente figura:


Clic derecho y se mostrará el menú contextual, del cual seleccionar la primera opción: "Cargar Datos" y se listarán los productos.


Serialización Binaria

Clic derecho y del menú contextual seleccionar la opción "Binario" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 11 msg y se creará un archivo llamado "Binario.txt" con el siguiente contenido:


Notas
- Si se intenta Serializar el archivo a Binario se caerá ya que la Entidad (clase beProducto) no es serializable, proceder a descomentar el atributo [Serializable].
- Observar que el tamaño del archivo Binario.txt es de 5756 bytes (en mi caso).

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 8 msg y se cargarán los datos desde el archivo "Binario.txt" en la lista de objetos y se mostrará en la grilla.

Serialización SOAP

Detener la ejecución y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "SOAP" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 30 msg y se creará un archivo llamado "SOAP.txt" con el siguiente contenido:


Nota: Observar que el tamaño del archivo SOAP.txt es de 73586 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 51 msg y se cargarán los datos desde el archivo "SOAP.txt" en la lista de objetos y se mostrará en la grilla.

Serialización XML

Detener la ejecución y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "XML" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 192 msg y se creará un archivo llamado "XML.txt" con el siguiente contenido:


Nota: Observar que el tamaño del archivo XML.txt es de 22270 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 209 msg y se cargarán los datos desde el archivo "XML.txt" en la lista de objetos y se mostrará en la grilla.

Serialización JSON sin atributos

Detener la ejecución y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "JSON" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 474 msg y se creará un archivo llamado "JSON.txt" con el siguiente contenido:


Nota: Observar que el tamaño del archivo JSON.txt es de 19716 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 347 msg y se cargarán los datos desde el archivo "JSON.txt" en la lista de objetos y se mostrará en la grilla.

Serialización JSON con atributos (DataContract y DataMember)

Detener la ejecución, decomentar los atributos [DataContract] y [DataMamber] de la entidad beProducto, además renombrar el archivo JSON.txt por JSON2.txt y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "JSON" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 27 msg y se creará un archivo llamado "JSON.txt" con el siguiente contenido:



Nota: Observar que el tamaño del archivo JSON.txt es tan solo de 10332 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 92 msg y se cargarán los datos desde el archivo "JSON.txt" en la lista de objetos y se mostrará en la grilla.

Serialización Personalizada con Strings

Detener la ejecución y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "Personalizado" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 15 msg y se creará un archivo llamado "Strings.txt" con el siguiente contenido:



Nota: Observar que el tamaño del archivo Strings.txt es de 3125 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Personalizado" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 53 msg y se cargarán los datos desde el archivo "Strings.txt" en la lista de objetos y se mostrará en la grilla.

Resumen Comparativo

A continuación una figura con un cuadro resumen de tiempos y tamaños por serializador (formato):



Esta resaltado los que mejor rendimiento tienen, es decir el tiempo de Serializado el ganador es el Binario, pero en tamaño (ancho de banda) el ganador es el Strings (Personalizado), además para Servicios Web el Binario no es aplicable por tanto, el mejor Serializador en Performance sería el String.

Sin embrago el comportamiento de los desarrolladores ha sido:
- Web Services XML con SOAP (2002-2007)
- WCF Services con XML (2008-2011)
- Web API con JSON (2012-2015)

Comentario Final

Después de haber tratado detalladamente los Serializadores .NET y analizado su tiempo y tamaño, la recomendación final es que si desean consumir el mínimo ancho de banda, hay que crear su propio serializador (yo le estoy dejando el mio, que poco a poco lo voy a optimizar) ya que es el que mejor rendimiento tiene en velocidad, tamaño e inter-operabilidad.

Claro, muchos dirán que No es Estandar el formato creado, y otros dirán y como hago para consumirlos desde los clientes, es decir como muestro estos datos, así como hay Templates para JSON yo tambien tengo mis propias rutinas que muestran en JavaScript cualquier Strings separados por caracteres, los cuales serán motivos de otros post.

Descarga del Código