DCE2005 (Estrella 0)
El programa llamado, Desarrollador 5 Estrellas (DCE2005), es una alternativa de capacitación en línea para aquellos profesionales que se encuentran inmersos en el mundo de los lenguajes de programación, desarrollo de software, y demas aspectos relacionados con tecnologías de desarrollo que ofrece Microsoft.
Desde hace algún tiempo me entere de éste, y siempre he tenido la inquietud de poder finalizar con éxito este programa, no por el hecho de sentirme atraido por las tecnologías de Microsoft (ya que me apasiona cualquier otra), sino por las oportunidades de crecimiento que ofrecen, mas aún, ya que en mi actual trabajo predominan los desarrollos en estas tecnologías.
El objetivo de este post (y los que vienen) es poder platicar un poco sobre lo visto en cada uno de los niveles (estrellas para ser coherentes), no con el fin de enseñar, si no mas bien de poder dar un overview de los que nos podemos encontrar en estos niveles de autocapacitación.
Dentro del primer set de materiales en este programa estan los relacionados tres temas escenciales en el entendimiento de todo el programa:
- Fundamentos de Programación.
- Introducción a la Orientación a Objetos.
- Introducción a la Programación Orientada a Objetos.
Casi a ciencia cierta puedo comentar que con el primero y el tercero tenemos para acreditar nuestra primera estrella (son de los que hablaremos en este post) ya que el segundo se desarrolla con mas contenido en los proximos materiales o niveles por decirlo así (al menos asi le funciono a su servidor), pero nunca esta de mas poder revisar la información, de hecho es recomendable.
Este primel nivel tiene como objetivo explicar los aspectos escenciales de .NET y los fundamentos de software y programación, claro que si alguien ya con algo de experiencia en el ramo, podrá pasarlo sin problemas ya que toca aspectos que nada tienen que ver con la plataforma de desarrollo de Microsoft o sus derivados (a excepción del tema Programación Orientada a Objetos, que se enfoca a lenguajes de programación propios de la plataforma .NET), si no mas bien aspectos que competen a cualquier lenguaje de programación o plataforma de desarrollo.
★ Fundamentos de Programación
Tiene como objetivo, dar una introducción a los conceptos escenciales en lo que se refiere a la programación de aplicaciones informáticas. Todo aquello necesario y que requerimos saber para el buen funcionamiento de las mismas. Toca temas tan genericos como el Software partiendo de su definición; Lenguajes de Programación (maquina, bajo nivel y alto nivel), su descripción; La Resolución de Problemas con Computadora y su implicación ademas las fases que envuelve (análisis del problema, diseño del algoritmo, codificación, verificación, depuración y documentación).
En este primer tema tambien se define lo que es un Entorno de Programación (IDE) a muy grueso modo, describiendo sus componentes mas comunes (editor, interprete o compilador, depurador y ayuda en línea).
Los Tipos de Datos se definen como piezas de información con las que un programa de computación trabaja. Este es otro tema que se analizan en este nivel del programa, objetivos de los mismos y su implicación. Involucra tambien un poco del entorno de las Variables y Constantes, la diferencia entre cada una; Sentencias, definición y clasificación; Operadores y Expresiones, definición, clasificación y tipos.
Hay un tema que sobresale en este primer punto del nivel y es el relacionado a Estructuras de Control, aquellos métodos que permiten modificar el orden en que se ejecutan acciones individuales de un programa para un flujo de control. Una buena parte del material se detiene en esta sección. Se definen los tipos de estructuras de control: de Selección (IF, CASE) y las Repetitivas (WHILE, FOR) y se muestran algunos ejemplos aplicativos.
Otra sección a destacar en la que describe los Procedimientos y Funciones (grupos de sentencias a los que se les asigna un nombre), se diferencia entre ambos, se establece como se realiza comunicación entre ellos (parametros, que se pueden clasificar en parametros de entrada y de salida), y se mencionan algunas ventajas de usar procedimientos y funciones en las aplicaciones. Por último el tema muestra información relacionada a la Visibilidad de Variables, tipos y descripción; Bibliotecas (assemblies), descripción; Arreglos, que es lo que las caracteriza, descripción y clasificación (unidimensionales, bidimensionales).
★ Introducción a la Programación Orientada a Objetos
Junto con el otro, este es un tópico escencial para la comprensión de las futuras estrellas en el programa. Este tema trata sus ejemplos con los mas populares lenguajes de programación con los que cuenta la plataforma .NET: VB.NET y C#.NET, al menos los mas usados por mis co-workers. Algunas diferencias entre estos dos lenguajes:
C#.NET:
- Creado especialmente para .NET.
- Estándar ECMA (2002) - European Computer Manufacturers Asociation.
- Orientado a objetos y componentes.
- Sintáxis derivada de lenguajes OO, tales como: C, C++, Delphi y Java.
VB.NET:
- Rediseñado especialmente para .NET.
- 100% orientado a objetos y componentes.
- La sintaxis es casi misma de Visual Basic 6.0 y sus predecesoras.
- Tienes la misma potencia, robustez y capacidad de acceso a .NET que C#.NET.
Introducción a la POO nos introduce es lo mas escencial hablando de programación para estos dos lenguajes. Compiladores, Tipos de Datos (Enteros, Punto Flotante, Lógicos y Otros), Alcance de Miembros (en C# todo miembro es declarado como private por default, mientras que en VB es declarado public), Declaración de Variables son algunos de los temas básicos vistos en esta sección. La Inicialización de Variables, Conversion de Tipos, Arreglos, Operadores, Constructores son temas un poco mas interesantes. Y de los mas trascendentes estan: Métodos (acciones que un objeto puede llevar a cabo), Sobrecarga de Métodos (varios métodos con el mismo nombre pero diferente firma), Métodos Estáticos (miembros que no requieres de una instancia para ser invocados), Propiedades (caracteristica o atributo de un objeto), Herencia, Espacios de Nombre (método de organización lógico de clases) y la Administración de Excepciones.
Es muy grato, pero a veces muy mortificante saber que en muchas de las ocasiones las cosas que creemos básicas y sencillas, no necesariamente son asi. Hay mucho que aun tenemos que aprender y conceptualizar. Este programa hasta hoy en su primer escalon me ha ayudado a reflexionar sobre ciertos aspectos que para nada debemos de dejar a un lado.
Espero que esta entrega les sea un poco de apoyo para el logro de su estrella escentials. Y con la tarea de seguir escribiendo sobre aquellos temas que deberemos de tomar en cuenta para seguir abriéndonos paso en este programa.
Instalando plantillas de VSTS 2008 para proyectos de SQL Server 2008
Un día de estos intentaba crear un proyecto de Base de Datos en mi Visual Studio Team System 2008 (VSTS), pero al momento de intentar seleccionar la plantilla el Wizard de Visual Studio solo me permitía agregar proyectos de Base de Datos SQL Server 2000 y 2005, la razón, la desconocía. Pensé que la solución era instalar el Service Pack 1 (SP) para Visual Studio 2008 pero tampoco funciono. Después de revisar en algunos foros del MSDN, en algunos comentarios mencionaban que para poder utilizar las plantillas requería de la última versión Community Technology Preview (CTP) del VSTS GDR Edición Base de Datos 2008, que al final de cuentas es un parche que nos va a permitir utilizar las plantillas para la creación de proyectos de Base de Datos en el VSTS 2008.
El CTP requiere de:
Instalador y documentación lo podemos descargar desde:
¡Suerte con su desarrollo!
NHibernate for dummies
Sabemos hoy en día que la mayoría de las empresas basan sus aplicaciones en software analizado, diseñado y programado orientado a objetos. La empresa donde trabajo, los últimos meses se ha preocupado porque que cada vez en los desarrollos que se venden se utilicen objetos para crear modelos de negocio, que con esto, sin duda si creamos un modelo de dominio orientado a objetos será más claro el negocio para que el que lo necesite entender y código fácil mucho mas mantenible para los programadores que lo vayan a modificar.
Por otro lado tenemos la información, los datos, y probablemente todos nosotros en nuestros desarrollos hemos trabajado con bases de datos relacionales tales como SQL Server, MySQL, entre otras. Esta información seguramente necesitara cambiar e irse modificando, así como también necesitaremos tener esta información disponible cuando queramos, esto en al área de desarrollo de sistemas se le conoce como persistencia. Como se relaciona esto? el modelo relacional de datos es la representación más clara de los objetos de negocio que existen en nuestro dominio de sistema y este necesitara almacenar información de cada una de sus entidades dentro del mismo dominio (Clientes, Productos, Usuarios, etc) y al conjuntarse nace un concepto conocido como Object Relational Mapping (ORM).
NHibernate (NH) es un marco de trabajo ORM para ambientes en los que utilizamos .NET que nace de un port de Hibernate de Java y la gran utilidad es que ayuda a mapear los objetos de negocio que creamos en nuestras aplicaciones de .NET a bases de datos relacionales.
A partir de ahora intentaremos explicar cómo funciona a grandes rasgos NH y como podríamos aplicarlo a los nuevos desarrollos en la empresa. Para la práctica estaremos utilizando la versión 2008 del Visual Studio Team System (VSTS 2008) como IDE de desarrollo y la versión express del SQL Server 2005.
1. Crear un proyecto biblioteca de clases
Este proyecto deberá de contener nuestros objetos de negocio, y por lo tanto aquellos objetos que deseamos persistir. Como ya hemos mencionado en otros tutoriales, se recomienda como buena práctica crear un archivo de solución (sln) y en este agregar tantos proyectos vayamos a necesitar.

Para este tutorial he creado un proyecto llamado Tutorial.NH.BOL que es la biblioteca de clases que contendrá las entidades que representaran la base de datos.
2. Crear modelo de dominio
Nuestro modelo de dominio estará basado en usuarios (crearemos una carpeta con nombre Entidades en nuestro proyecto para depositar nuestras clases) y las diversas tareas que puede tener un usuario, sabemos que nuestras aplicaciones empresariales son más complejas, pero creo que bastará con explicar lo esencial para entender lo que es NH. La idea de esto es poder persistir estas entidades en nuestra base de datos relacional. Para hacer más sencillo el entendimiento de NH imagínense que una instancia de cada una de nuestras entidades en una fila de una tabla de la base de datos, pero no se casen con este concepto.
Es una buena práctica usar el diagramador de clases que por defecto cuenta el VSTS 2008, el trabajo es más limpio, mas controlado y lo mejor de todo en la mayoría de los casos ¡no tenemos que escribir código! =).

3. Crear modelo relacional
El modelo relacional estará representado por aquellas tablas de base de datos las cuales deberán de representar las entidades del modelo de dominio que queremos persistir. Ya sea en el IDE de VSTS 2008 o en la consola de Microsoft SQL Server deberemos de obtener algo como esto (algo ideal sería utilizar NH para generar el esquema de nuestra base de datos acorde a nuestro modelo de dominio, este método queda fuera del alcance del tutorial):

4. Mapeo ORM
La manera en cómo se mapeara el modelo de dominio con nuestro modelo relacional es a través de documentos XML, esto se hace con el fin de documentar la relación que existe entre nuestro objeto y la tabla que lo representa en la base de datos, es decir, el documento de configuración define que campos en la base de datos corresponden a los atributos en nuestro objeto y viceversa. La relación puede hacerse mediante código (con ayuda de la librería NHibernate.Mapping.Attributes.dll) en los atributos de la clase ó a través de archivos como los que acabo de comentar, archivos XML que tienen la extensión .hbm.xml, es por esto que nuestros archivos mapping deberan llamarse Usuario.hbm.xml y Tarea.hbm.xml. No hay que perder de vista que el .hbm es parte del nombre del archivo y es una convención que utiliza NH para identificar los archivos como mapping
Antes de empezar a trabajar con nuestro mapeo ORM debemos de descargar la versión 1.02 de NHibernate para .NET, la cual está disponible en la siguiente dirección: http://downloads.sourceforge.net/nhibernate/NHibernate-1.2.0.GA-bin.zip?modtime=1178204756&big_mirror=0
Se recomienza habilitar el Intellisense para el mapeo y la creación de estos archivos de configuración, para esto debemos de copiar los archivos nhibernate-configuration.xsd (para la configuración de las sesiones, algo que veremos más adelante en este tutorial) y nhibernate-mapping.xsd (para los mappings) a las carpetas de instalación de Visual Studio <VS .NET directorio de instalación>Common7Packagesschemasxml si usamos VS.NET 2003 y <VS 2005 directorio de instalación>XmlSchemas para VS.NET 2005 y 2008.
Dentro de nuestra librería de clases Tutorial.NH.BOL vamos a crear una carpeta llamada Mapping -esto con el fin de tener mas orden- la cual contendrá todos nuestros archivos de configuración y la implementación de estos la muestro a continuación:
4.1. Usuario.hbm.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| <?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Tutorial.NH.BOL" namespace="Tutorial.NH.BOL">
<class name="Usuario" table="usuarios">
<id name="Id" column="IdUsuario" type="int" unsaved-value="0">
<generator class="identity" />
</id>
<property name="Nombre" type="String" length="50"></property>
<property name="ApellidoMaterno" type="String" length="50"></property>
<property name="ApellidoPaterno" type="String" length="50"></property>
<property name="CorreoElectronico" type="String" length="50"></property>
<property name="Telefono" column="TelefonoParticular" type="String" length="50"></property>
<bag name="Tarea" cascade="all-delete-orphan">
<key column="IdUsuario" />
<one-to-many class="Tarea" />
</bag>
</class>
</hibernate-mapping> |
Ahora podemos hablar un poco sobre el contenido del archivo XML. Todos los documentos para mapear XML deberán de declarar el espacio de nombre urn:nhibernate-mapping-2.2 (depende de la versión distribuida), así como de manera opcional los atributos assembly para indicar el ensamblado de nuestras clases y el namespace de nuestras clases en el proyecto. Existen otros atributos aplicables a nuestro archivo como el schema, que representa el nombre del esquema de la base de datos, entre otros que están fuera del alcance de este tutorial. Una vez hecho esto debemos de comenzar a tratar los atributos y elementos para la clase que deseamos mapear. Dentro de las etiquetas <class name=”Usuario”></class> estarán todas aquellas configuraciones para la clase. El atributo name corresponde al nombre de la clase incluyendo el nombre del assembly. El atributo table corresponde al nombre de la tabla en la base de datos.
Con la etiqueta <id> representamos la llave primaria de la tabla de la base de datos. Este elemento define el mapeo entre la propiedad de la clase y la llave primaria de la base de datos. Entre sus atributos se encuentra el name, que indica el nombre del identificador de la propiedad; columna, que representa la columna en la tabla; type, el tipo de dato y el unsaved-value indica que el objeto es nuevo y que no existe en la base de datos.
Debemos de continuar con todas las propiedades, entonces Nombre, Apellido Paterno, Apellido Materno, Correo Electronico y Telefono deberán de estar dentro de las etiquetas <property/> y representan propiedades persistentes de la clase.
Y como habíamos dicho al inicio del tutorial, lo complicaremos creando una relación one-to-many con la clase Tarea y de esta forma representaremos la relación en la base de datos, es decir, que a un usuario se le pueden asignar varias tareas.
4.2. Tarea.hbm.xml
1
2
3
4
5
6
7
8
9
10
| <?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Tutorial.NH.BOL" namespace="Tutorial.NH.BOL">
<class name="Tarea" table="tareas">
<id name="Id" column="IdTarea" type="int" unsaved-value="0">
<generator class="identity" />
</id>
<property name="NombreTarea" type="String"></property>
<many-to-one name="Usuario" column="IdUsuario" cascade="all" />
</class>
</hibernate-mapping> |
Lo único representativo es el elemento <many-to-one> para la propiedad Usuario de nuestra clase. Esta representa una ordinaria asociación a otra clase persistente, en este caso la que tenemos en la base de datos.
Algo que debemos de saber es que en primera instancia NH está configurado de modo perezoso (lazy load) para todas las entidades creadas. Esto se recomienda dejarse así y no moverse. Debido a esto la regla es que todas las propiedades definidas en nuestras entidades deberán ser virtuales.
1
2
3
4
5
| public virtual int Id
{
get { return _id; }
set { _id = value; }
} |
Hay mucha más información relacionada a estos archivos mapping, pero sería algo complicado tratar de explicárselos paso a paso, además de que este tutorial perdería sentido, para ello, recomiendo consultar la referencia en línea sobre este mapeo de clases en http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/mapping.html.
Hasta aquí nuestro explorador de soluciones deberá verse así:

5. Configurando NHibernate en VSTS 2008 .NET
Bueno hasta ahora, no hemos hecho mucho, pero ya empieza lo bueno =). Hay que decirle a NH con que proveedor de base de datos vamos a trabajar. Por fortuna NH soporta el más querido por nosotros en la oficina SQL Server.
Para hacer mas modular la aplicación, vamos a agregar una aplicación de consola a nuestra solución con el fin de consumir nuestro ORM. El nombre que yo le he puesto al proyecto es Tutorial.NH.App, tu puedes ponerle el que gustes. Importante agregar dentro de las referencias nuestro ensamblado de nombre Tutorial.NH.BOL. Pudimos haber utilizado Unit Test para probar nuestro proyecto en lugar de la aplicación de Consola, pero mejor eso veámoslo después.
5.1. Configuración en App.config
Agregaremos un archivo de configuración donde indicaremos las llaves necesarias para establecer la comunicación con nuestra base de datos.
1
2
3
4
5
6
7
8
9
10
11
12
13
| <?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<nhibernate>
<add key="hibernate.show_sql" value="false" />
<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" />
<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<add key="hibernate.connection.connection_string" value="Data Source=ROBERTOSQLEXPRESS;Initial Catalog=NHibernate;Integrated Security=SSPI;" />
</nhibernate>
</configuration> |
5.2 Configuración en hibernate.cfg.xml
Este es otra manera de realizar nuestra configuración de NH y consiste en agregar un archivo XML a nuestro proyecto con la siguiente estructura: hibernate.cfg.xml.
1
2
3
4
5
6
7
8
9
10
11
| <?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory name="NH01">
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<property name="connection.connection_string">Data Source=ROBERTOSQLEXPRESS;Initial Catalog=NHibernate;Integrated Security=SSPI;</property>
<property name="show_sql">false</property>
<mapping assembly="Tutorial.NH.BOL" />
</session-factory>
</hibernate-configuration> |
Podemos utilizar cualquiera de los dos. Con este archivo de configuración le decimos a NH que queremos trabajar con Microsoft SQL Server como base de datos. Para nuestro ejemplo usaremos la segunda opción.
Y bien ya estamos listos para iniciar con nuestras operaciones CRUD.
6. Operaciones CRUD
Nuestro sistema hasta este punto ha sido preparado con lo esencial. Se han implementado características necesarias para el funcionamiento de NH, se ha creado el modelo de dominio se han definido los archivos mapping y se ha establecido la configuración a NH. Vamos poco a poco y ya llevamos algo recorrido =).
Empezaremos a darle uso y funcionalidad a nuestro dominio.
Ahora, vamos a agregar una carpeta a nuestro proyecto Tutorial.NH.BOL llamado Repositorio (esto lo especifica Domain Driven Design) y en el agregaremos una clase llamada IRepositorioUsuario.cs y la definimos de la siguiente manera:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| using System;
using System.Collections.Generic;
using System.Text;
using Tutorial.NH.BOL.Entidades;
namespace Tutorial.NH.BOL.Repositorio
{
public interface IRepositorioUsuario
{
void Agregar(Usuario usuario);
void Actualizar(Usuario usuario);
void Eliminar(Usuario usuario);
Usuario ObtenerUsuarioPorId(int IdUsuario);
IList<Usuario> ObtenerUsuarios();
}
} |
Ahora, lo que sigue es implementar cada uno de los métodos definidos por la interfaz IRepositorioUsuario.cs. Comenzaremos con el primer método Agregar() que nos va a permitir agregar una instancia de un Usuario en nuestra base de datos.
Dentro de la misma carpeta (Repositorio) vamos a agregar una clase llamada RepositorioUsuario.cs y vamos a hacer que herede de la interfaz IRepositorioUsuario.cs, con esto haremos que la clase implemente cada uno de los métodos de la interfaz.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| using System;
using System.Collections.Generic;
using System.Text;
using NHibernate;
using Tutorial.NH.BOL.Entidades;
using Tutorial.NH.BOL.Genericos;
namespace Tutorial.NH.BOL.Repositorio
{
public class RepositorioUsuario : IRepositorioUsuario
{
public void Agregar(Usuario usuario)
{
throw new NotImplementedException();
}
public void Actualizar(Usuario usuario)
{
throw new NotImplementedException();
}
public void Eliminar(Usuario usuario)
{
throw new NotImplementedException();
}
public Usuario ObtenerUsuarioPorId(int IdUsuario)
{
throw new NotImplementedException();
}
public IList<Usuario> ObtenerUsuarios()
{
throw new NotImplementedException();
}
}
} |
Ahora, lo que sigue es crear el mecanismo para crear las sesiones que se van a comunicar con nuestra base de datos. Dentro del mismo proyecto, nos crearemos una Carpeta que nombraremos Genericos y agregamos una clase de nombre NHibernateClass.cs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Cfg;
namespace Tutorial.NH.BOL.Genericos
{
public class NHibernateClass
{
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
var configuration = new Configuration();
configuration.Configure();
_sessionFactory = configuration.BuildSessionFactory();
}
return _sessionFactory;
}
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
} |
Esta clase lo que hará por nosotros es crear una SessionFactory solo la primera vez que el cliente necesita una sesión. Que contiene este Singleton? Contiene un objeto del tipo Configuración que utiliza la configuración de nuestro hibernate.cfg.xml que creamos en la aplicación se escritorio y que se encarga de cargar el objeto ISessionFactory gracias al método BuildSessionFactory() y de esta forma poder comenzar a crear sesiones de tipo ISessionFactory.
Volvamos a nuestra clase RepositorioUsuario.cs e implementemos el método Agregar() de la siguiente manera:
1
2
3
4
5
6
7
8
9
| public void Agregar(Usuario usuario)
{
using (ISession sesion = NHibernateClass.OpenSession())
using (ITransaction trans = sesion.BeginTransaction())
{
sesion.Save(usuario);
trans.Commit();
}
} |
En el método Actualizar() escribiremos lo siguiente:
1
2
3
4
5
6
7
8
9
| public void Agregar(Usuario usuario)
{
using (ISession sesion = NHibernateClass.OpenSession())
using (ITransaction trans = sesion.BeginTransaction())
{
sesion.Update(usuario);
trans.Commit();
}
} |
En el método Eliminar() escribiremos lo siguiente:
1
2
3
4
5
6
7
8
9
| public void Agregar(Usuario usuario)
{
using (ISession sesion = NHibernateClass.OpenSession())
using (ITransaction trans = sesion.BeginTransaction())
{
sesion.Delete(usuario);
trans.Commit();
}
} |
Para el método ObtenerUsuarioPorId() haremos esto:
1
2
3
4
5
| public Usuario ObtenerUsuarioPorId(int IdUsuario)
{
using (ISession sesion = NHibernateClass.OpenSession())
return sesion.Get<Usuario>(IdUsuario);
} |
Y para obtener todos los usuarios:
1
2
3
4
5
6
7
8
| public IList<Usuario> ObtenerUsuarios()
{
using (ISession sesion = NHibernateClass.OpenSession())
{
var usuarios = sesion.CreateCriteria(typeof(Usuario)).List<Usuario>();
return usuarios;
}
} |
Nota la creación del objeto sesión desde nuestra clase NHibernateClass.cs y tambien el uso de una transacción.
¡Y listo! podemos empezar a trabajar con nuestro modelo de NH para la persistencia de nuestras entidades de dominio.
Para guardar la información de un usuario y sus tareas una posible implementación es que desde nuestra aplicación de consola incluyamos esta implementación:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tutorial.NH.BOL.Entidades;
using Tutorial.NH.BOL.Repositorio;
namespace Tutorial.NH.App
{
class Program
{
static void Main(string[] args)
{
Usuario usr = new Usuario();
usr.Nombre = "Roberto";
usr.ApellidoPaterno = "Ramirez";
usr.ApellidoMaterno = "Leyva";
usr.CorreoElectronico = "jramirezleyva@gmail.com";
usr.Telefono = "410-00-00";
Tarea task = new Tarea();
task.NombreTarea = "Tutorial de NHibernate";
task.Usuario = usr;
usr.Tarea.Add(task);
IRepositorioUsuario rUsr = new RepositorioUsuario();
rUsr.Agregar(usr);
}
}
} |
Si bien recordamos cuando hicimos el modelo de dominio y las mapeamos con la base de datos, creamos unas propiedades que permitían las relaciones <many-to-one />, <one-to-many />. Esta es la verdadera magia, ¿se dieron cuenta que nunca utilizamos procedimientos almacenados o que nunca nos creamos rutinas de conexión y de creación de DataAdapters o DataSets, mucho menos DataReaders? Gracias a NH podemos persistir nuestros objetos de una manera limpia y orientada a objetos que es lo más importante.
Conclusión
En este sencillo ejemplo, pudimos observar cómo manejar un modelo de dominio y como cerrar el “gap” con nuestra base de datos relacional. Sabemos que este es un ejemplo básico y hay mucho más que explicar y que probar, pero por lo pronto espero que esto les haya servido como una introducción (al menos a mí si me ayudo jeje).
El código de ejemplo lo pueden descargar de aqui.
Mas información:
http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/
http://darioquintana.com.ar/articles/tutorial-de-nhibernate-primeros-pasos
Escribiendo una regla de análisis de código para VSTS 2008
FxCop es una herramienta Open Source que ayuda al análisis de ensamblados de código mediante reglas y reporta información relacionada de esos ensamblados, la cual puede referirse a rubros como el de seguridad, diseño, rendimiento, todo aquello relacionado a reglas aplicables a los ensamblados (para mas información).
Después de conocer que esta herramienta viene integrada en la versión Team System de Visual Studio .NET 2008 (en realidad ya venía integrada desde versiones anteriores) en la empresa donde laboro decidieron ajustar las reglas o estándares de codificación internas utilizadas, a todo aquel ensamblado generado en los proyectos.
El objetivo era generar código estandarizado y que mejor que el Code Analysis para lograrlo y usarlo para crear políticas de generación de buils, es decir, no permitir compilar el proyecto si no cumplimos con los estándares internos.
A partir de este párrafo verán algo de lo que pude realizar para crear una regla de análisis de código que verifique el nombramiento de los elementos de interfaz grafica.
1. Crear biblioteca de clases
Nuestro primer paso será de los más sencillo, crear un proyecto de tipo biblioteca de clases que contendrá las clases que define la regla para verificar el nombramiento de los elementos de interfaz grafica de nuestras aplicaciones (es una buena práctica definir un archivo de tipo solución de proyecto y en esta ir agregando todos los proyectos que necesitemos).

2. Agregar referencias
Debemos de incluir nuestras referencias a la librería de FxCop que se encuentra dentro de la ruta: Archivos de programa\Microsoft Visual Studio 9.0\Team Tools\Static Analysis Tools\FxCop (podria variar dependiendo del idioma y sistema operativo y al menos en un XP en español es la misma). Estas representan el framework que contiene las clases necesarias para poder diseñar nuestra regla.
- FxCopSdk.dll. Para acceder a la interfaz IIntrospectionRule que permitirá identificar aquellas clases de ensamblados que son reglas de Code Analysis, que implementa la clase BaseIntrospectionRule.
- Microsoft.Cci.dll.

3. Crear la clase base
Para poder implementar los métodos de la interfaz IIntrospectionRule, es necesario crearnos una clase abstracta (que nosotros llamaremos BaseRule) que herede o implemente la clase BaseIntrospectionRule. Más o menos quedaría así:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.FxCop.Sdk;
using Rules.Naming.Globales;
namespace Rules.Naming
{
public abstract class BaseRule : BaseIntrospectionRule
{
protected BaseRule(string name) : base(name, Constantes.Config_Rules, typeof(BaseRule).Assembly) { }
}
} |
Noten que he agregado una clase (Constantes.cs) que contendrá aquellas variables constantes para nuestra regla. Yo ahí he colocado la variable que representara nuestro archivo de recursos (un archivo xml, pero aun no te preocupes por conocerlo, mas adelante lo podrás observar).
1
2
3
4
5
6
7
8
9
10
11
12
13
| namespace Rules.Naming.Globales
{
/// <summary>
/// Clase estática que contiene los valores constantes.
/// <summary>
public static class Constantes
{
/// <summary>
/// El nombre del recurso embebido. Xml que contiene las reglas.
/// <summary>
public const string Config_Rules = "Rules.Naming.Rules";
}
} |
4. Crear la regla de Code Analysis
Bien, ¡estamos listos para crear nuestra regla!, habíamos comentado que nuestra regla validaría el nombramiento de elementos de interfaz grafica de nuestras aplicaciones, entonces como primer punto debemos de agregar una clase nueva a nuestro proyecto (es una buena práctica nombrar a la clase con un nombre que haga referencia a la regla). Nuestra clase se llamara VerifyGUINaming.cs y la definición se muestra a continuación.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.FxCop.Sdk;
namespace Rules.Naming
{
/// <summary>
/// Esta clase nos permitirá diseñar una regla para realizar análisis de código
/// a los elementos de interfaz gráfica de la aplicación.
/// <summary>
public class VerifyGUINaming : BaseRule
{
public VerifyGUINaming() : base("VerifyGUINaming") { }
}
} |
Como se puede observar lo primero que tenemos que hacer es agregar la referencia a nuestra biblioteca de clases de FxCop y después hacer que la misma herede de la clase base (BaseRule.cs) que hemos definido (no olviden documentar todo lo que hagan). Hasta aquí ya se encuentra definida la regla, pero aun no hace nada jojojo!.
5. Implementando el metodo Check()
Empecemos con lo nice de esto. Debemos de implementar el método Check() que contiene la clase BaseIntrospectionRule que permitirá reportar cualquier problema (¿recuerdan al inicio del tutorial? ) referente a la definición y los deposita dentro de una clase ProblemCollection.
Nuestro código para verificar el nombramiento de un elemento de escritorio de tipo Button deberá de verse así:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| /// <summary>
/// Método que agrega a la colección de problemas en caso de no cumplirse la regla.
/// <summary>
/// <param name="member">Elemento a comparar.</param>
/// <returns>Un problema en caso de haberlo.</returns>
public override ProblemCollection Check(Member member)
{
Field campo = member as Field;
if (campo != null)
{
string nombreControl = campo.Type.FullName;
if (nombreControl.StartsWith("System.Windows.Forms.Button"))
{
if (!campo.Name.Name.StartsWith("btn_"))
{
Problems.Add(new Problem(GetResolution("btn_", "System.Windows.Forms.Button", campo.Name.Name)));
}
}
else
{
return null;
}
}
else
{
return null;
}
return Problems;
} |
Si aun no sabes que es lo que recibe como parámetro (member) el método Check, entonces te puedo comentar que ese tipo representa los miembros que puede tener una clase, métodos, propiedades, eventos, delegados, etc. Existen otros elementos que analiza el método Check, pero como ya he escrito mucho sobre esto, tendrás oportunidad de echar un googlazo e investigar por tu cuenta.
6. Creando el esquema XML
Para dejar completa nuestra regla es necesario crear nuestro archivo XML que describirá información relacionada a aquellos problemas encontrados al momento de analizar el código del ensamblado, en otras palabras, el código mostrado determina si hay un problema, el archivo XML lo describe de mejor forma.
Como primer paso habrá que agregar a nuestro proyecto un archivo con extensión xml y escribir lo siguiente:
1
2
3
4
5
6
7
8
9
10
11
12
13
| <?xml version="1.0" encoding="utf-8" ?>
<Rules FriendlyName="Code Analysis Rules">
<Rule TypeName="VerifyGUINaming" Category="Rules.Naming" CheckId="NR0001">
<Name>Nombramiento de elementos de interfaz gráfica</Name>
<Description>Para el nombramiento de los elementos de interfaz gráfica el identificador del control se deberá escribir en minúscula anteponiendo al identificador un prefijo que indique el tipo de elemento grafico que es separado por un guión bajo. Esto ayudara a distinguir los elementos de interfaz grafica.</Description>
<Url></Url>
<Resolution>Reemplazar el identificador del control "{2}" por su correcto nombramiento de interfaz gráfica: "{0}".</Resolution>
<MessageLevel Certainty="95">Error</MessageLevel>
<FixCategories>Breaking</FixCategories>
<Email>jramirezleyva@gmail.com</Email>
<Owner>Roberto Ramírez</Owner>
</Rule>
</Rules> |
El nombre del recurso si bien recuerdan lo definimos en nuestra clase Constantes.cs y se indica en la clase base BaseRule.cs
Algo muy importante es decirle a nuestro proyecto que este archivo de reglas XML deberá de comportarse como un recurso embebido a nuestro ensamblado.

7. Usando nuestra regla de análisis de código
Hasta este paso lo que obtenemos como resultado es un ensamblado que contiene la definición de nuestra regla, y lo que debemos de hacer es probarla.
Para que esto sea posible debemos manualmente copiar nuestra regla (ensamblado) al folder de nuestra versión de Visual Studio, como el titulo dice que es para la versión VSTS 2008 nuestro folder se encuentra en esta dirección: C:\Archivos de programa\Microsoft Visual Studio 9.0\Team Tools\Static Analysis Tools\FxCop\Rules, normalmente lo único que cambia es la versión del Visual Studio.
Una vez finalizado esto, cerramos y abrimos nuestro Visual Studio. Tu puedes crear un nuevo proyecto a agregarlo a la solución para hacer la prueba de análisis de código, en este caso puedes agregar un proyecto de escritorio para revisar el elemento de interfaz grafica Button.
Ya que tengamos nuestro proyecto veremos sus propiedades y en la pestaña de análisis de código (Code Analysis) veremos algo muy similar a esto:

Dando por hecho que en nuestra aplicación de escritorio de prueba tenemos un botón sin el prefijo “btn_” en la forma y corriendo el Code Analysis en nuestra aplicación podemos ver lo siguiente:

Nota que lo que nos arroja el análisis de código en un problema de tipo Warning, dejando que nuestro proyecto compile, si al inicio hablamos de código estandarizado entonces deberemos de configurar nuestra aplicación para que no compile en caso de no cumplirse las reglas. Para esto lo único que debemos de hacer es darle a la regla un trato de error en nuestro archivo XML y en la configuración de las propiedades del proyecto habilitar las opciones de “Manejar la regla como error” y “Habilitar Code Analysis en el Build” como se muestra en la imagen:

Con esto no permitiremos compilar código si antes no cumplimos con nuestras reglas.
Espero que esto los ayude.
vsts.2008
La semana que acaba de pasar me ha resultado muy provechosa, particularmente en mi comprensión sobre algunas tecnologías de desarrollo de Microsoft y tomando en cuenta que en mi actual trabajo es el pan de todos los días el desarrollar software con estas, pues en este primer intento de acercamiento, he quedado muy satisfecho por muchos aspectos. Uno de estos aspectos es que el cuate que nos visito y nos dio el overview del VSTS.2008 nos ha dejado con un buen sabor de boca, al menos conmigo en lo particular si lo hizo. Segundo, la herramienta viene a darnos o mas bien viene a revolucionar creo yo en mi humilde punto de vista la manera en como desarrollamos el software en la empresa. Es mucho el potencial que tenemos al alcance con esta herramienta y sabiendola utilizar es muy seguro que podremos mejorar nuestros hábitos de programación.
Los tags de la presentación: sqlinjection, blindsqlinjection, vsts2008, nhibernate, nunit, unittest, importaciadelaspruebasunitarias, linq, microsoft, firefox3, deployment, df, novutek, dotnet, seguridad, iis, desarrolloguiadosporpruebas, refactoring, workitem, codesecurity, reflection, fxcode, performance, tipos de pruebas, desarrollo, basededatos, sonora, 50°C, soa, sqlserver2008, codeanalisis, mejorespracticas, teamfoundationserver, wfs, controldeversiones.
Por ahi se me pasaron varios, pero son los que se me vienen a la mente.
Delegados en .NET
Ya desde hace un buen tiempo, desde que ando en esto del desarrollo de software he escuchado sobre los Delegados, pero nunca los había entendido hasta hoy. Puedo escribir algo sobre lo que yo entiendo sobre ellos, pudiera ser que alguien tenga una mejor opinión, entonces leeré todos sus comentarios.
Partiendo de la definición de Delegados como una estructura de programación que nos permite invocar a uno o varios métodos a la vez. Estos métodos pueden encontrarse en la misma clase desde la que se invocan o en clases distintas asociadas a ésta. Hablando “a bajo nivel”, un delegado es un puntero seguro a una función (pero sin la complejidad de la administración propia de dicho puntero).
En palabras cristianas un Delegado no es nada más que un puntero a una función definida previamente en alguna clase. Se debe de definir la firma y el tipo devuelto del Delegado de la misma forma en que se define la función utilizando la palabra reservada delegate, quedandonos la implementación de la siguiente manera:
1
2
3
| public class DelegateTest {
private delegate string NombreDelegado (string Param1, …);
} |
Podemos hacer uso de los métodos definidos en las clases a través del Delegado. La instancia del delegado creado deberá de pedir como parámetro un método que puede ser la función a la que queremos apuntar -¿interesante no?- el IDE de Visual Studio solicita el parámetro de este tipo gracias a la definición del delegado creado anteriormente.
La ventaja de usar el Delegado como tal es que podemos utilizar los métodos de las funciones tal y como si estuviéramos creando una instancia de la función. Otra ventaja que resulta interesante es que podemos utilizar Delegados para desencadenar la llamada a varios métodos ya sea que estén en una clase o en clases por separado; esto es posible gracias a la combinación de dos o más Delegados definidos mediante el método estático combine que devuelve un Delegado genérico el mismo tipo del Delegado -ojo, no del mismo tipo de retorno del delegado sino del tipo tal delegate.
Como podemos ver la aplicación de Delegados los debemos de orientar a resolver problemas de ingeniería y de esta forma poderlos simplificar.
Ya después describiré algún uso en un proyecto futuro.
Teaching asp.net?
Fue bonito mientras duro. La experiencia fue muy significativa debido a que nunca habia experimentado la docencia. Ahora entiendo a mis maestros y todo lo que implica el impartir conocimiento a sus alumnos.
Hice mi mejor esfuerzo y me falta mucho por mejorar, pero creo que esta vez, salí muy bien librado de esta.
Oh MySQL!
En el proyecto en el que estoy, tengo que diseñar y construir scripts para migrar información de una base de datos de MySQL a otra base de datos diseñada en SQL Server 2005.
¿Pero a que problemas se podría enfrentar alguien como yo, al cuál le han impuesto trabajar con DMBS´s como el segundo en cuestión?
Pues primeramente, para alguien que no tiene ni la mas remota idea de como manejar MySQL - como yo - pues nos enfrentamos al primer problema: ¿como rayos restaurar una base de datos de MySQL? y es que uno esta acostumbrado a la interfaz bonita (o al menos funcional y gráfica) del Enterprise del SQL, en la cuál con dos clics tenemos nuestra base de datos ya lista para utilizar nuestros amplios conocimientos en DDL y DML (a-há). Pero bueno, aqui algo de lo que hice y que les sirva a otras personas:
Primeramente intente con PHPMyAdmin, el problema es que cuenta con un límite de tamaño y el back a restaurar pesaba mas de 400 megas o.O
Solo había otra forma de hacerlo o al menos la conocida no hasta ayer por mi, la fabulosa MySQL Command Line Client. Solo hay que usar este cliente para crear la base de datos mediante este comando:
1
| mysql>CREATE DATABASE NombreBD; |
Una vez que tenemos la base de datos en nuestro servidor hay que irnos a la línea de comandos de Windows inicio –> ejecutar y escribir cmd (al menos asi se hace en Windows XP) y escribir esto dentro del directorio bin de la instalación de MySQL en nuestro equipo:
1
| C:\Program Files\MySQL\MySQL Server 5.1\bin>mysql -uuser -p NombreBD>back.sql |
La línea de comando nos solicitará la contraseña del usuario y una vez proporcionándolo tendremos nuestra base de datos lista, restaurada al 100%.
Disclaimer: escribo este post para que en el futuro no me olvide de hacer esto, hehe.
Libros gratis!
En el blog de Carlos Leopoldo hay una interesante liga que nos podria interesar a varios. esta es la recopilación de algunos libros de programación web bajo la licencia Creative Commons.
http://www.carlosleopoldo.com/post/libros-gratis-de-diseno-web/
Hay que cultivarnos pues’n.
Scripts
Si hay un script que me ha facilitado la existencia al momento de habilitar vistas html, sin duda es este:
function showElements(element, display){
document.getElementById(element).style.display = display;
}
Lo he encontrado de verdad muy últil =)