yaml, una alternativa para XML
yaml es un lenguaje de serialización de datos, una alternativa al lenguaje de marcado XML. Es muy interesante, y es muy útil usarlo por que es más legible para el ojo humano que un archivo XML. Está enfocado a la simplicidad. Vamos a ver un ejemplo tomado de la realidad, así es como luciría un archivo de mapeo de NHibernate si fuera escrito en yaml:

Si usas NHiberante, debes darte cuenta que esto es mucho más fácil de leer. Como se puede apreciar la delimitación es hecha por identación. Si conoces lenguajes como Python esto te resultará muy familiar. Por supuesto, esto no está soportado en NHibernate, pero quien sabe, quizás alguien quiere donar algunas horas al OSS y hacerlo
Quizás una notoria desventaja es que yaml no posee esquema (schema). Y podés darte cuenta de las características que nos estamos perdiendo por esto, la más importante: validación de un documento yaml.
En .Net-landia no es tan popular, de hecho no lo es, pero en lenguajes como Python, Php, Perl, C++ se usa mucho. En el nuevo bebé de Google: Google App Engine, el cual tiene como lenguaje principal a Python (actualmente es el único lenguaje que soporta), usa yaml para los archivos de configuración.
Linking assemblies
Linker, es una libreria que escribió Jb, y se encarga de reducir al mínimo el conjunto de funciones assemblies para que un conjunto de programas puedan correr. En otras palabras, toma las librerias que necesita un programa y elimina de ellas los métodos ó tipos que no son necesarios.
Pueden obtener el código del SVN, y compilarlo. Requiere Mono.Cecil.
Linker es una simple aplicación de consola, y toda la magia ocurre en una sola linea de comandos. Antes que nada, veamos que tenemos. Los archivos necesarios para que la aplicación Mono.Sms.exe funcionen son: Castle.Core.dll, Castle.Windsor.dll, Castle.MicroKernel.dll y Castle.DynamicProxy.dll. Ponemos todos archivos en el mismo directorio que el ejecutable Mono.Sms.exe. Luego ejecutamos:
monolinker -a Mono.Sms.exe -out linkedfiles/ -x descritor.xml
Donde indicamos cual va a ser la aplicación objetivo, el directorio de salida, y el archivo xml descritor con los tipos que se desean preservar despues del proceso de linkeo. Nuestro archivo con los tipos que no queremos que Linker los eliminie es el siguiente:
<?xml version="1.0" encoding="utf-8" ?> <linker> <assembly fullname="Castle.Windsor"> <namespace fullname="Castle.Windsor.Configuration.Interpreters.XmlProcessor.ElementProcessors"/> <type fullname="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler"/> </assembly> </linker>
Con esto indicamos que el namespace ElementProcessors, y el tipo CastleSectionHandler deben ser incluidos en la salida. Este descritor lo tuve que elaborar porque Linker omitia el tipo CastleSectionHandler, y tambíén eliminaba los constructores de los tipos contenidos en el namespace ElementProcessors. Como lo supe? Prueba y error.
Ahora veamos el resultado:
Ahora que hemos reducido, el tamaño de los assemblies, imaginense otra herramienta para juntar todos los assemblies en 1 sólo. La filosofía XCOPY de .Net, se convertiria en la COPY, nada más. Por estos caminos anda también Jb, que según dijo, está reescribiendo a monomerge (actualmente se cae).
Compilando y Configurando Mono.Sms con NAnt en Ubuntu
Veamos como bajar y compilar Mono.Sms desde el código fuente en Ubuntu:
Para hacerlo debemos considerar tener un repositorio que contenga la version de Mono 1.2.4, con versiones anteriores no va a funcionar. Entonces hacemos:
$sudo apt-get install mono mono-gmcs mono subversion
$svn checkout http://monosms.googlecode.com/svn/trunk/ monosms
$cd monosms/
$nant
y con esto es suficiente para compilar Mono.Sms desde el SVN. Y para correrlo:
$cd build/
$mono Mono.Sms.exe
Previamente a lanzar la aplicación quizás querramos configurarla, para esto dentro de la sección monosms en el archivo Mono.Sms.exe.config se encuentran algunos parámetros:
<monosms> <settings> <add name="user.name" value="Jorge" /> <add name="user.email" value="usuario@monosms.com.ar" /> <add name="smtp.server" value="mail.gigared.com"/> </settings> </monosms>
Imágenes como recursos en los assemblies
Cuando trabajamos con Visual Studio/Sharpdevelop, podemos agregar en un pictureBox una imagen. Lo podemos hacer de 2 maneras (a simple vista): como Project Resource file ó Local Resource.
Ahora bien, otra manera de hacer esto, es añadiendo al proyecto las imágenes y declarándolas como Recursos Embebidos, para eso se podría crear una carpeta. Y después para obtener dichas imagenes utilizariamos un helper que nos retorne los recursos embebidos.
Así es como se está realizando el manejo de imágenes/iconos en Paint.Net. También copié el mismo esquema (y código) para Mono.Sms. Lo bueno del esquema que utiliza Paint.Net es que permite tener imágenes personalizadas dependiendo de la cultura:
Cuando Paint.Net necesita una imagen, lo solicita a la clase PdnResources, y esta hace lo siguiente:
- Verifica si posse una imagen personalizada según la Cultura, si encuentra la devuelve.
- Sino, busca dentro del assembly por imagenes embebidas, si encuentra la devuelve.
Al momento de buscar una imagen para asignarla a un pictureBox podemos hacer esto:
pictureBox.Image = PdnResources.GetImage("image.png");
El archivo PdnResources puede encontrarse aquí, y la manera que trata los recursos la considero como una buena práctica.
Mono.Sms contiene todas las imágenes embebidas de esta misma manera. Así se ven los recursos de Mono.Sms con Reflector:

Mono.Sms preview
Ya está para descargar Mono.Sms, hosteado como proyecto en Code Google.
Los binarios han sido probados en Mono 1.2.4/.Net Framework 2.0
Este es el trunk, pueden descargar el código fuente con un cliente de SVN como Tortoise SVNsi usan Windows.
Aquí están los binarios/setup para descargar:
Para dejar comentarios creé este grupo en google:
Voluntarios, envien los parches, reporte de issues/bugs aquí:
El código fuente se puede compilar usando NAnt. He incluido el archivo default.build en el SVN para este fin.
Nuevo screenshot de Mono.Sms
Esta screenshot fue tomada corriendo en .Net Framework de Microsoft. Dentro de poco liberaremos la release.
Mono.Sms y Windsor Container
Para ponerle un poco de sabor al Core de Mono.Sms, una de las cosas que me encargué de añadir es la capacidad solicitar los proveedores que estén disponibles para enviar mensajes por medio de un container de IoC. Para los que no sepan que es esto, pueden tener una introducción aquí con Spring.Net, o aquí utilizando Windsor.
Para dicha Inversion de Control (IoC) estoy usando Windsor Container.
Este caso todos los proveedores son inyectados, es decir, dejo que el container me entregue en mano, todas la implementaciones existentes de IProvider para la aplicación. Cada proveedor implementa la interfaz IProvider:
namespace Mono.Sms.Core.Provider { public interface IProvider { string Name { get; set; } string Domain { get; set; } bool UseSmtp { get; set; } string HostName { get; set; } string DataPost { get; } string Sign { get; } string Message { get; set; } CelNumber CelNumber { get; set; } int NumberOfCharacters { set; get; } string Description { get; set; } } }
y luego configuro los proveedores para que Windsor sepa sobre ellos y pueda crear los objetos:
<castle> <components> <component id="ProviderPersonalPost" service="Mono.Sms.Core.Provider.IProvider, Mono.Sms" type="Mono.Sms.Core.Provider.PersonalProvider, Mono.Sms" lyfestyle="singleton" > <parameters> <Name>Personal</Name> <Domain>@personal-net.com.ar</Domain> <UseSmtp>false</UseSmtp> <HostName>host25.200-43-139.telecom.net.ar</HostName> <Port>80</Port> <NumberOfCharacters>138</NumberOfCharacters> <Description>Este proveedor permite la entrega de mensajes a un celular Personal</Description> </parameters> </component> <component id="ProviderPersonalMail" service="Mono.Sms.Core.Provider.IProvider, Mono.Sms" type="Mono.Sms.Core.Provider.PersonalProvider, Mono.Sms" lyfestyle="singleton" > <parameters> <Name>Personal</Name> <Domain>@personal-net.com.ar</Domain> <UseSmtp>true</UseSmtp> <HostName>host25.200-43-139.telecom.net.ar</HostName> <Port>80</Port> <NumberOfCharacters>110</NumberOfCharacters> <Description>Este proveedor permite la entrega de mensajes a un celular Personal utilizando mails.</Description> </parameters> </component> </components> </castle>
En este caso hemos creado 2 implementaciones para enviar mensajes a una misma empresa, una forma es haciendo un post, y la otra utilzando mails. Hablando en el idioma de Windsor container, hemos creado aquí 2 Componentes (ProviderPersonalPost y ProviderPersonalMail), para un mismo Servicio (IProvider).
Luego para pedirle al container que nos entregue todas las implementaciones de los servicios IProvider, realizo esta siguiente iteración:
public IList<IProvider> GetAllProviders() { IHandler[] handles = container.Kernel.GetHandlers(typeof (IProvider)); IList<IProvider> providersImpl = new List<IProvider>(); foreach (IHandler hdlr in handles) { providersImpl.Add((IProvider)hdlr.Resolve(CreationContext.Empty)); } return providersImpl; }
Se puede ver que agrego a una lista providersImpl todos los proveedores y los retorno. Y con esto tengo en mano a todos los proveedores con los que puedo mandar mensajes.
Se preguntarán: “Es necesario todo esto para una simple aplicación de sms?”, la respuesta es “No”. Como se sabe, IoC es un principio de diseño, y no un requerimiento indispensable.
Opiniones ? Sientanse como en casa
Mono.Sms para enviar mensajes
Mono.Sms es una aplicación que se escribió para mandar mensajes de texto en Argentina a clientes de empresas como Personal, Cti, y Movistar. La ventaja es que lo podemos correr tanto en Linux y Windows. Aquí les mando un screenshot del preview:
Dentro de poco se podrá bajar el binario para usarlo, con los nombres de los coders de esta app.
Iteraciones en C# – capturas de pantalla
En este post previo, hablábamos sobre las iteraciones en C# y donde dije que Mono me resultó un poco más rápido en Linux a diferencia con Mono en Windows y .Net Framework de MS. Bueno aquí les muestro las resultados de las ultimas corridas de cada uno para que vean. La clase con la que probé se encuentra aquí: Iteraciones.zip
Con .Net Framework de MS:
Con Mono en Windows:
Con Mono en Linux: