viernes, 28 de agosto de 2009

Modelo de Compilación y Ejecución del .NET Framework

En este artículo, revisaremos el modelo de ejecución del .NET Framework, el proceso de compilación y revisar internamente un ensamblado.

¿CÓMO SE CONSTRUYE UN ENSAMBLADO?

Todo ensamblado está implementado a partir de un lenguaje de programación soportado por el .NET Framework: C#, Visual Basic, etc., cada uno de estos lenguajes, sólo proporciona su sintaxis y compilador para convertir el código fuente a un archivo compilado en lenguaje intermedio (Intermediate Language), el cual puede ser un archivo EXE ó DLL (ensamblado). En el siguiente gráfico puede observar el proceso de compilación.

Compilacion

Una vez generado el ensamblado, será desplegado hacia la PC del usuario o servidor, donde el .NET Framework se encuentra instalado como prerrequisito.

¿QUÉ SUCEDE DURANTE LA EJECUCIÓN DEL ENSAMBLADO?

Luego de desplegar el ensamblado, su ejecución queda bajo responsabilidad del .NET Framework, el cual, proporciona una serie de servicios que habilitan un ambiente seguro para la ejecución (managed code) dentro del CLR (Common Language Runtime), entres los que podemos nombrar:

  • El Motor de ejecución JIT (Just In Time Activation), este servicio, se encarga de tomar la porción de código que necesita ser ejecutada (On Demand), y lo convierte a lenguaje de máquina, esto es necesario, debido a que el procesador donde ejecuta el ensamblado, puede ser diferente al que se usó para su construcción.
  • Garbage Collection: este proceso se encarga de ir monitoreando los recursos que ya no son empleados por la aplicación, para ser depurados a partir de Heap del sistema (repositorio de las instancias de objetos en desuso), o también cuando la aplicación requiere recursos, aquí es importante recalcar que el objeto responsable de liberar los recursos es el Garbage Collector (GC), el cual NO DEBE ser ejecutado desde la aplicación por motivos de performance.
  • Seguridad: esta característica, permite controlar el acceso a los recursos del ensamblado, ya sea a partir de la identidad de otro ensamblado (Code Access Security – CAS), o la entidad de un usuario (Role Base Security – RBS), para lo cual, un ensamblado debe tener asociado un Nombre Seguro (Strong Name) de esto hablaremos más adelante.

En el siguiente gráfico podemos observar el trabajo del CLR durante la ejecución de un ensamblado.

EjecucionCLR

CONTRUYENDO UN ENSAMBLADO Y ANALIZANDOLO POR DENTRO.

En este ejemplo, vamos a construir un ensamblado empleado el Visual NotePad :-) , y haremos uso del compilador del lenguaje, para luego analizar la estructura interna del ensamblado.

Paso 1: Abrir una ventana del Block de Notas de Windows: Inicio – Ejecutar – Notepad [ENTER].

Paso 2: Ingrese las siguientes líneas de código, respetando el uso de mayúsculas y minúsculas.

C#

DemoCSharp

VB

DemoVB

Paso 3: Grabe el archivo en un directorio de trabajo (Ejemplo: C:\DemosNet\), asigne como nombre de archivo: DemoNet.cs ó DemoNet.vb (hasta esta parte hemos implementado el código fuente según el primer gráfico)

Paso 4: Ingrese a la línea de comandos del Visual Studio .NET 2008: Inicio – Programas – Microsoft Visual Studio 2008 – Visual Studio Tools – Visual Studio 2008 Command Prompt.

Paso 5: Desde la línea de comandos, ingrese a la carpeta de trabajo: C:\> CD DemosNet [ENTER].

Paso 6: Dependiendo del lenguaje de su preferencia, haga uso del compilador respectivo (posiblemente se puede mostrar una advertencia al compilar en C#, esto no es crítico):

CS

CompilaCS

VB

CompilaVB

En el directo se habrá generado el archivo DemoNet.exe, el cual procederemos a ejecutar (hasta esta parte se ha construido el ensamblado, según el gráfico).

Paso 7: Desde el directorio de trabajo, en la línea de comando de Visual Studio 2008, escriba: C:\DemosNet>DemoNet.exe [ENTER], observe el resultado.

DemoEjecuta

Paso 8: Para revisar la estructura del ensamblado, desde la línea de comandos, escriba la siguiente sentencia:

C:\DemosNet>ILDASM DemoNet.exe [ENTER]

Esto mostrará la ventana del Intermediate Language Disasembler, donde puede observar el Manifiesto del ensamblado y su contenido (clases compiladas).

ILParte1

Ingrese al Manifiesto del ensamblado, en esta sección se puede localizar parte de la identidad del ensamblado como: versión, llave pública (todo esto forma parte del nombre seguro, esto será configurado desde Visual Studio).

ILParte2Manifiesto

Cierre la ventana anterior, e ingrese al código del método Main.

ILParte3

Puede notar porqué el ejemplo se trató de una mala práctica, muchos podemos cometer el error de exponer data sensible como: cadenas de conexión, rutas, etc, esto puede estar a disposición de personas no autorizadas, ¿Qué pasa con esto?, ¿El .NET Framework es inseguro?, ¿Ya no debo seguir pensando en usar .NET?, pues nada de eso, todo es un esquema de diseño de sus aplicaciones, en el cual debe considerar los mecanismos de seguridad a aplicar (De esto trataré en el siguiente artículo.).

Hagamos el papel de un Hacker Junior, y vamos a alterar el archivo de forma maliciosa (se imaginan una sentencia SQL, el cual en vez de “Select * From Usuarios”, alguien lo reemplace por “Delete From Usuarios”), es muy serio el tema de seguridad, veamos.

Paso 9: Cierre la ventana anterior, y desde el menú del ILDASM, seleccione:

FileDump 

Paso 10: Acepte las configuraciones por defecto (clic en el botón OK), e ingrese como nombre de archivo: DemoNet.IL, y proceda a grabar.

GrabarIL

Cierre la ventana del ILDASM, y regrese a la línea de comandos del Visual Studio 2008.

Paso 11: Desde el explorador de Windows, edite el archivo DemoNet.IL, y reemplace el valor de la variable a alterar y grabe los cambios.

HackCarpeta

Paso 12: Antes de recompilar el lenguaje intermedio, elimine el ensamblado anterior: C:\DemosNet>DEL DemoNet.exe [ENTER].

Paso 13: Proceda a recompilar el ensamblado usando la siguiente sentencia.

Recompilar

Paso 14: Proceda a ejecutar nuevamente el ensamblado y observe los resultados.

ResultadoHack

Puede notar que el resultado ha cambiado, y no hubo ningún mecanismo que evite esto, PERO por ninguna razón estoy afirmando que el .NET Framework es inseguro.

CONCLUSIONES FINALES.

En este artículo, hemos conocido cómo trabaja el proceso de compilación y ejecución del .NET Framework, y también cómo es la estructura de un ensamblado, en los próximos artículos hablaremos acerca de los mecanismos de seguridad y de cómo evitar que un ensamblado sea modificado, aunque personalmente, esto me ha ayudado en alguna oportunidad, pero puede ser mal aplicado.

Por último, el ILDASM e ILASM, son parte de las herramientas de línea de comandos del .NET Framework, que iremos conociendo más adelante, sólo hay que tener en cuenta, que en un ambiente de producción, no todas las herramientas están disponibles, ya que son parte del .NET Framework SDK. Hasta la próxima.

viernes, 21 de agosto de 2009

Generalidades del .NET Framework

En   este   artículo   conoceremos  los   conceptos  básicos   del   .NET Framework, y cómo podemos comenzar a desarrollar aplicaciones con Visual Studio .NET 2008.

Muchos amigos me han sugerido compartir parte de mi experiencia en el mundo de .NET, y aprovecho la oportunidad para agradecerles por este reto personal. Para muchos, esta tecnología puede tener sus falencias, pero como dijo un gran amigo mío: "No hay tecnología mala, sino mal aplicada", y que siempre debemos buscar una forma práctica y óptima de hacer las cosas, para lo cual siempre tendremos a la mano a "Dr. Google".

CONOCIENDO EL .NET FRAMEWORK.

El .NET Framework se define como la plataforma de desarrollo de aplicaciones basados en la tecnología .NET, conformada por los siguientes componentes:

Common Language Runtime (CLR): encargado de ejecutar y monitorear las aplicaciones .NET, a través de servicios que hacen posible un entorno más administrado (Managed Code), que a diferencia de los motores de ejecución de versiones anteriores (ejemplo: VB 6.0), dependían del sistema operativo (Unmanaged Code).

Librerías de Clase Base: conformado por los componentes o ensamblados requeridos para construir cualquier aplicación soportada por el .NET Framework, ejemplo: aplicaciones de escritorio (Win32), librerías dinámicas (DLL), páginas Web, servicios Windows, servicios Web, aplicaciones móviles, etc. Los componentes o ensamblados, se organizan de forma jerárquica a través de Namespace , ejemplo:
  • System: Namespace principal, donde localizamos la definición de los tipos de datos nativos del .NET Framework, como: Int32, Int64, Boolean, String, etc.
  • System.Collection: aquí localizamos las clases para definir colecciones o arreglos, ejemplo: ArrayList, Dictionary, HashTable, etc.
  • System.Data: aquí localizamos las clases principales para trabajar con ADO.NET y consumir un origen de datos. 

    Importante: se recomienda aplicar esta nomenclatura cuando configure sus propias librerías, ejemplo: Rze.Tools.dll, Rze.Security.BusinessEntities.dll}
Lenguaje de Especificación Común (CLS): encargado de administrar la compatibilidad en el uso de tipos (enteros, alfanuméricos, etc), cuando los componentes de una aplicación se implementen en diferentes lenguajes.

Importante:
cuando haga uso de diferentes lenguajes para los componentes de su aplicación, procure respetar las equivalencias en los tipos de datos, esto optimiza la integración en tiempo de ejecución.

Cada uno de los componentes del .NET Framework, se encuentran identificados en el siguiente gráfico:


 Figura 1: Arquitectura del .NET Framework.
    En el gráfico anterior, podemos distinguir la arquitectura del .NET Framework 3.5, la cual incluye nuevas extensiones como:
    • ASP.NET MVC: permite el desarrollo de páginas Web, basado en el patrón Model-View-Controller (esto fue incorporado en SP1 del .NET Framework 3.5).

    • Ajax: permite una interacción asíncrona desde el Browser del cliente, con el servidor Web de nuestra aplicación.

    • LINQ (Language Integrated Query): permite emplear sintaxis de consulta para diferentes tipos de orígenes de datos, ejemplo: colecciones, DataSets, XML.

    • Entity Framework: permite manejar un modelo de objetos para diferentes orígenes de datos, manejando la persistencia de datos (operaciones contra un origen), basado en código .NET.

    • WPF (Windows Presentation Foundation): permite la mejora visual de las aplicaciones a tavés del uso de XAML (eXtensible Application Markup Language), el WPF incorpora como mejora principal el uso de los aceleradores de gráfico (Codecs)

    • WCS (Windows CardSpace) permite el uso de tokens de identificación para aplicaciones que ejecuten bajo Windows XP SP2 ó superior.

    • WWF (Windows Workflow Foundation) permite implementar procesos de negocio basados en Workflows, y podemos integrarlo con otras plataformas como Microsoft Office SharePoint Server 2007 (MOSS).

    • WCF (Windows Communication Foundation) permite implementar servicios para aplicaciones distribuidas, y es la plataforma base actual de Microsoft para la construcción de soluciones basadas en SOA (Services Oriented Architecture).

    En los próximos artículos, trataremos más a detalle acerca de los componentes mencionados.

    ¿QUÉ ES UN ENSAMBLADO?.

    Para el .NET Framework, la unidad mínima de ejecución es el ensamblado (Assembly) el cual se representa como un archivo de extensión EXE o DLL.

    El ensamblado, es el resultado de la compilación de las clases que conforman una aplicación, recuerde que la unidad mínima de cualquier tipo de aplicación en .NET es una clase. (es importante recordar que Visual Basic aún mantiene el uso de módulos, sólo para fines de compatibilidad).

    Al crear una aplicación haciendo uso de una plantilla de Visual Studio .NET, el resultado final será un ensamblado, el que será desplegado al cliente, donde el prerrequisito principal, es que el .NET Framework se encuentre instalando (a excepción de las aplicaciones Web, donde el despliegue se hace sólo en el Servidor Web).

    Importante: puede existir la posibilidad que la aplicación Web, requiera que el cliente instale el .NET Framework, esto se da cuando intentamos ejecutar un ensamblado a través de la página Web, la cual se descarga al cliente para su ejecución, por ello la necesidad del .NET Framework. (Se recomienda implementar esto sólo en escenarios de aplicaciones Web para Intranets).

    CREANDO NUESTRA PRIMERA APLICACIÓN CON VISUAL STUDIO .NET 2008.

    En este ejemplo, vamos a implementar un ensamblado de tipo EXE, empleando el entorno de desarrollo de Visual Studio .NET 2008.

    Paso 1: Inicie el entorno de Visual Studio .NET 2008, ingresando a: Inicio - Programas - Microsoft Visual Studio 2008 – Microsoft Visual Studio 2008.

    Paso 2: Desde el menú principal de Visual Studio, seleccione el File - New - Project, esto activará la ventana de plantillas de Visual Studio.


    Paso 3: En la sección Project Types, seleccione el lenguaje de preferencia, y en la sección Templates, el tipo de proyecto Console Application, configure el nombre del proyecto y la carpeta de trabajo, luego haga clic en OK.


    Paso 4: El nuevo proyecto se crea, y puede visualizar su contenido desde el Explorador de Soluciones, (para activar el explorador de soluciones, haga clic en el menú View - Solution Explorer).


    Importante: Una solución puede contener más de un proyecto, y cada uno puede ser configurado con un lenguaje de programación diferente. Se recomienda emplear un nombre diferente para la Solución.

    Paso 5: En la aplicación de consola, podrá encontrar un archivo principal, para C# es el archivo Program.cs, y para Visual Basic, Module1.vb, en el cual se encuentra definido un método de nombre Main, que será el primer procedimiento en ejecutar al inciar el programa. Implementar Las siguientes líneas de código según el lenguaje de preferencia:

    C#

    VB

    Importante: para hacer uso de un Namespace, en C# hace uso de la palabra reservada using, y para VB, Imports, en algunas plantillas, estas líneas de código ya se incluyen, para este ejemplo, en VB tendrá que agregar la línea de código: Imports System.Text.

    Paso 6: El ejemplo pretende comparar los métodos de concatenación tradicionales con la clase StringBuilder, para proceder a ejecutar la aplicación, pulse la tecla F5, y observe los resultados.


    Podrá notar que la diferencia es muy representativa, y que incluso el primer bucle se ejecutó 10,000 itearciones, y el segundo, 100,000 iteraciones, a pesar de ello, el uso de StringBuilder es más óptimo (recuerde que esta clase se encuentra en el Namespace System.Text).

    Paso 8: Desde el explorador de soluciones, haga clic sobre el botón Show All Files, esto mostrará las carpetas donde se generan los resultados del ensamblado.



    Observe que aparecen las siguientes carpetas:

    • OBJ. es donde el ensamblado se graba durante el momento de compilación de la solución, esta ruta se emplea para leer las rutas relativas que puede estar empleando el ensamblado, recuerde que sólo es en el momento de compilación.
    • BIN. es donde se almacena el ensamblado compilado, a partir de esta carpeta se realizará la ejecución. Puede apreciar que aparece una sub carpeta DEBUG, esto se debe a que estamos trabajando en modo Depuración, lo cual significa que podemos hacer seguimiento al código, y que el ensamblado puede generar información de depuración (esto siempre que se usen los métodos de la clase Debug que se localiza en el Namespace System.Diagnostics).

    Importante: una vez que el ensamblado se encuentre listo para ser desplegado, se recomienda compilar la aplicación en modo RELEASE, lo cual optimizará el tamaño del archivo compilado, es importante recalcar que no se trata de optimización de la ejecución del código, ya que esto dependerá de las buenas o malas prácticas que haya aplicado en su codificación, ejemplo: concatenar con un operador tradicional y no con la clase StringBuilder.

    Cambie el modo de compilación de Debug a Release, desde la barra de herramientas de Visual Studio.


    Si procede a compilar la solución (Ctrl + Shift + B / combinación de teclas para compilar la solución), observer la carpeta que será añadida al explorador de soluciones (Nota: el archivo de extensión .pdb no requiere ser desplegado).


    Grabe los cambios y finalice el Visual Studio.

    Con este ejemplo, he querido dar a conocer la forma de construir un ensamblado, además del uso de un Namespace del .NET Framework desde C# y VB. Espero haya sido de gran utilidad para aquellas personas que están iniciándose en el desarrollo con .NET, hasta la próxima...