2.- Componentes Fundamentales


2.1.- Arquitectura del .NET Framework

En la imagen se pueden apreciar las distintas partes que componen al .NET Framework, incluidas el entorno de ejecución de aplicaciones, el conjunto de bibliotecas de funcionalidad reutilizable (.NET Framework Class Library) y los compiladores y herramientas de desarrollo para los lenguajes .NET. Todos estos componentes se montan por encima de la familia de sistemas operativos Windows.

Dentro del conjunto de la .NET Framework Class Library se distinguen 4 sub-componentes principales:

          La Base Class Library (BCL - Biblioteca de Clases Base), que contiene la funcionalidad más comúnmente utilizada para el desarrollo de todo tipo de aplicaciones. Algunos ejemplos de la funcionalidad provista por la BCL son el manejo de colecciones, cadenas de texto, entrada/salida, threading, operaciones matemáticas y dibujos 2D.

          ADO.NET, que contiene un conjunto de clases que permiten interactuar con bases de datos relacionales y documentos XML como repositorios de información persistente.

          ASP.NET, que constituye la tecnología dentro del .NET Framework para construir aplicaciones con interfaz de usuario Web (es decir, aplicaciones cuya lógica se encuentra centralizada en uno o varios servidores y que los clientes pueden acceder usando un browser o navegador mediante una serie de protocolos y estándares como HTTP y HTML).

          Windows Forms (o simplemente WinForms), que constituye la tecnología dentro del .NET Framewok que permite crear aplicaciones con interfaz de usuario basada en formularios y ventanas Windows de funcionalidad rica y que se ejecutan directamente en los clientes.

CLR Arquitectura de Ejecución de Aplicaciones


El modelo de ejecución que propone la plataforma .NET se suele definir como “virtual”, o “de máquina virtual”, ya que las aplicaciones no son desarrolladas directamente contra las APIs de programación expuestas por el sistema operativo, ni es éste el que se encarga de su ejecución y ciclo de vida, sino que .NET provee un entorno de ejecución (el CLR) que corre por sobre el sistema operativo y que es el encargado de ejecutar las aplicaciones y proveerles servicios en tiempo de ejecución. A los componentes de software que se ejecutan de esta manera se los conoce comúnmente como “componentes manejados”, ya que su ejecución es controlada por un entorno intermedio. En la figura podemos ver las diferencias entre las arquitecturas de ejecución de los componentes tradicionales (como los COM) y los componentes manejados.

Una de las principales ventajas de contar con una plataforma virtual es que no están “atadas” de ninguna forma con el sistema operativo y la plataforma de hardware subyacente. Es sabido que una aplicación compilada para que utilice directamente las APIs y servicios expuestos por un sistema operativo “x” muy difícilmente  pueda ser ejecutada en otro sistema operativo distinto sin ser recompilada. Las aplicaciones manejadas, en cambio, descansan la tarea de su compilación a un código de máquina específico en el entorno de ejecución. De esta manera, si existen distintos entornos de ejecución intermedia para diferentes Sistemas Operativos, la misma aplicación puede ejecutarse en todos ellos si necesidad de recompilarse.

2.2.- Common Language Runtime (CLR)

·         El CLR es el motor de ejecución (runtime) de .NET

·         Características

-          Compilación Just-In-Time (JIT)

-          Gestión automática de memoria (Garbage Collector)

-          Gestión de errores consistente (Excepciones)

-          Ejecución basada en componentes (Assemblies)

-          Gestión de Seguridad

-          Multithreading


Ya hemos visto como el CLR actúa como un motor de ejecución de aplicaciones y componentes manejados. Veamos ahora algunos de los principales servicios que les brinda a las aplicaciones que se ejecutan sobre él:

          Compilación Just In Time (o Justo A Tiempo): el CLR se encarga de compilar las aplicaciones .NET a código de máquina nativo para el sistema operativo y la plataforma de hardware en la que se está ejecutando. Esto lo hace sin intervención alguna del desarrollador o el usuario, y solamente a medida que se necesita.

          Gestión Automática de Memoria: el CLR abstrae a los desarrolladores de tener que pedir y liberar memoria explícitamente. Para esto, uno de sus componentes llamado Garbage Collector (Recolector de Basura) se encarga de liberar periódicamente la memoria que ya no está siendo usada por ninguna aplicación. Por otra parte, el CLR también abstrae a los desarrolladores del uso de punteros y del acceso a memoria de bajo nivel. Si bien estas características pueden ser consideradas poderosas, suelen hacer el desarrollo y mantenimiento de aplicaciones más propenso a errores y menos productivo.

          Gestión de Errores Consistente: como las aplicaciones .NET no se ejecutan directamente contra el Sistema Operativo, cualquier error no manejado que ocurra en tiempo de ejecución será atrapado por el CLR en última instancia, no afectando a ninguna otra aplicación que se esté ejecutando ni teniendo efecto alguno sobre su estabilidad.

          Ejecución Basada en Componentes: todas las aplicaciones .NET son empaquetadas en componentes reutilizables denominados genéricamente Assemblies, que el CLR se encarga de cargar en memoria y ejecutar. Profundizaremos sobre este tema más adelante en el curso.

          Gestión de Seguridad: el CLR provee una barrera más de contención a la hora de ejecutar aplicaciones manejadas, ya que permite establecer políticas de seguridad muy detalladas que las aplicaciones .NET que se ejecuten en una determinada computadora deberán cumplir.

          Multithreading: el CLR provee un entorno de ejecución multi-hilos por sobre las capacidades del Sistema Operativo, así como también mecanismos para asegurar su sincronización y acceso concurrente a recursos compartidos.

CLR Componentes Internos

CLR Proceso de Compilación


El desarrollo de una aplicación .NET comienza con la escritura de su código fuente en alguno de los lenguajes de alto nivel soportados por la plataforma. El mismo luego es compilado obteniéndose un ejecutable (que en Windows normalmente llevan la extensión .exe) o una biblioteca (que en Windows normalmente llevan la extensión .dll). A estos componentes .NET resultantes del proceso de compilación se los denomina genéricamente Assemblies, o Ensamblados.

Ahora bien, en lugar de contener código de máquina específico para el sistema operativo y el hardware en el cual fueron compilados (nativo), los assemblies contienen un código denominado MSIL (Microsoft Intermediate Language). EL MSIL es un set de instrucciones independientes de cualquier CPU existente y que puede ser convertido a código nativo muy eficientemente. MSIL incluye instrucciones para cargar, almacenar, inicializar e interactuar con objetos y sus atributos y métodos, así como también instrucciones aritméticas y lógicas, control de flujo, acceso directo a memoria, manejo de errores y otras operaciones. Antes de que el código MSIL pueda ser ejecutado debe convertirse a código nativo específico para un CPU y Sistema Operativo, tarea a cargo de los compiladores JIT incluidos en el CLR.

2.3.- Microsoft Intermediate Language

CLR MSIL

.method private hidebysig static void Main(string[] args) cil managed {

.entrypoint

maxstack 8

L_0000: ldstr "Hola Mundo"

L_0005: call void [mscorlib]System.Console::WriteLine(string)

L_000a: ret

}

Aquí podemos ver el tradicional método que imprime “Hola Mundo” por consola escrito en MSIL. Como se puede apreciar, el MSIL tiene ciertas similitudes con el assembler de x86, y en cierta forma podemos decir que es análogo a un assembler para la máquina virtual que constituye el CLR. Se puede apreciar también que el CLR se comporta como una máquina “de stack”, en la cual las instrucciones se van apilando y desapilando de a una para lograr la funcionalidad deseada.

Todos los compiladores de todos los lenguajes .NET producen código MSIL como salida, ya que es el único lenguaje capaz de ser comprendido e interpretado por el CLR.

El .NET Framework SDK incluye herramientas para obtener el código MSIL a partir de un ejecutable o biblioteca (ildasm.exe) y para generar un ejecutable o biblioteca a partir de un archivo fuente MSIL (ilasm.exe). Para más información sobre estas y otras herramientas se pueden consultar la documentación del SDK.

2.4.- Assemblies


¿Qué es en un Assembly?

Un Assembly es la unidad mínima de ejecución, distribución, instalación y versionado de aplicaciones .NET


Un Assembly es la menor unidad de ejecución y distribución de una aplicación .NET.

Los assemblies son reutilizables, versionables y autodescriptivos, ya que no sólo contienen el código MSIL que representa la lógica de la aplicación, sino que también incluyen información sobre si mismos y sobre todos los recursos externos de los que dependen para funcionar correctamente. A esta información se la denomina “MetaData”  y forma una parte integral de un assembly junto con el código MSIL ya que ambos no pueden estar separados. La MetaData se ubica en una sección especial del Assembly denominada “Manifest”, o “Manifiesto”, y es utilizada por el CLR a la hora de cargar y ejecutar el Assembly.

La herramienta ildasm.exe (Intermediate Languaje Dissasembler, incluida en el .NET Framework SDK) puede utilizarse para inspeccionar la metadata de un assembly.

Assemblies - Aplicaciones .NET

·         Uno o más Assemblies

·         Al ejecutar una aplicación, ¿cómo ubico los assemblies necesarios?

-          El Class Loader busca en el directorio local (preferido)

-          Global Assembly Cache (GAC)

  • Diferentes aplicaciones pueden usar diferentes versiones

-          Actualizaciones más simples

-          Desinstalación más simple

Una aplicación .NET se compone, entonces, de uno o más assemblies. Otra de las características de los Assemblies es que no necesitan estar registrados en la Registry de Windows, como sus predecesores COM. De esta forma, instalar una aplicación .NET puede ser tan simple como copiar todos los assemblies necesarios a la computadora de destino, y basta con borrarlos a todos para tener una desinstalación limpia y completa.

Dado que .NET no depende de la Registry, y que cada assembly contiene información acerca de su versión y las versiones de los componentes de que depende, múltiples versiones de assemblies pueden coexistir sin ningún problema en la misma computadora.

Existen dos formas de que una aplicación pueda encontrar en tiempo de ejecución los assemblies de los que depende:

1)       Ubicarlos en el mismo directorio. Esta es la opción preferida si esos assemblies sólo serán utilizados por esa única aplicación.

2)       Ubicarlos en un repositorio centralizado de assemblies denominado Global Assembly Cache, en el cual se instalan todos los assemblies que serán utilizados por múltiples aplicaciones en la misma computadora. Para registrar un assembly en el GAC es necesario utilizar otra herramienta incluida en el SDK llamada gacutil.exe.

2.5.- .NET Class Library

.NET Framework Class Library

·         Conjunto de Tipos básicos (clases, interfaces, etc.) que vienen incluidos en el .NET Framework

·         Los tipos están organizados en jerarquías lógicas de nombres, denominados NAMESPACES

·         Los tipos son INDEPENDIENTES del lenguaje de desarrollo

·         Es extensible y totalmente orientada a objetos

 

De muy poco serviría a los desarrolladores el contar con una plataforma de ejecución de aplicaciones tan sofisticada y robusta como el CLR sin tener además un conjunto de funcionalidades y componentes empaquetados listos para aprovechar y reutilizar en sus aplicaciones. Justamente ese es el propósito de la .NET Framework Class Library (Biblioteca de Clases del .NET Framework), que provee cientos de tipos básicos (clases e interfaces principalmente) orientados a objetos, extensibles mediante herencia, independientes del lenguaje de programación de alto nivel que se desee utilizar y organizados en namespaces jerárquicos.

.NET Framework Class Library

El namespace raíz es SYSTEM



En la figura se aprecian los principales namespaces de la biblioteca de clases .NET:

          System: raíz de todos los otros namespaces, y dentro del cual podemos encontrar la mayoria de los namespaces correspondientes a la Base Class Library

          System.Data y System.Xml: en conjunto, estos dos namespaces constituyen la tecnología conocida como ADO.NET

          System.Web: dentro de este namespace se encuentran todos los tipos necesarios para programar aplicaciones y servicios web ASP.NET

          System.Windows.Forms: dentro de este namespace se encuentran todos los tipos necesarios para programar aplicaciones de escritorio basadas en formularios y ventanas Windows.

2.6.- Common Language Specification (CLS)

·         Especificación que estandariza una serie de características soportadas por el CLR

·         Contrato entre diseñadores de lenguajes de programación y autores de bibliotecas

·         Permite la interoperabilidad entre lenguajes

·         Microsoft provee implementaciones de 4 lenguajes, todos compatibles con CLS

-          Microsoft Visual Basic .NET

-          Microsoft Visual C# .NET

-          Microsoft Visual J#.NET

-          Microsoft Visual C++.NET

Uno de los objetivos de diseño de la plataforma .NET fue el ser independiente del lenguaje de programación elegido para el desarrollo de aplicaciones. Para lograr esto es que se creó la Especificación de Lenguaje Común (o CLS, por sus siglas en inglés), que define y estandariza un subconjunto de todas las características soportadas por el CLR y que son necesarias en la mayoría de las aplicaciones. Todos los componentes desarrollados y compilados de acuerdo con la especificación CLS pueden interactuar entre sí, independientemente del lenguaje de programación de alto nivel en el que fueron escritos.

Junto con el .NET Framework, Microsoft provee implementaciones de 4 lenguajes compatibles con CLS, junto con sus compiladores:

          Microsoft Visual Basic .NET

          Microsoft Visual C# .NET

          Microsoft Visual J#.NET

          Microsoft Visual C++.NET

Esto quiere decir que una aplicación escrita, por ejemplo, en Visual Basic.NET, puede incorporar sin problemas nuevas partes escritas en C# o C++ .NET.

El resto de la industria y el sector académico han desarrollado más de 20 lenguajes compatibles con la especificación CLS.


Dado que la especificación CLS es un estándar disponible públicamente, ha sido posible que otros diseñadores de lenguajes y compiladores desarrollaran más de una veintena de lenguajes compatibles con la especificación, y por ende interoperables entre sí y con los lenguajes desarrollados por Microsoft.

CLS - Elección del lenguaje

·         .NET posee un único runtime (el CLR) y un único conjunto de bibliotecas para todos los lenguajes

·         No hay diferencias notorias de performance entre los lenguajes provistos por Microsoft

·         El lenguaje a utilizar, en gral., dependerá de su experiencia previa con otros lenguajes o de gustos personales

-          Si conoce Java, Delphi, C++, etc. à C#

-          Si conoce Visual Basic o VBScript  à VB.NET

  • Los tipos de aplicaciones .NET son INDEPENDIENTES del lenguaje que elija

Un punto importante a destacar es que la elección del lenguaje de alto nivel en el que debe escribirse una aplicación .NET prácticamente ha sido reducida a una cuestión de gustos personales y comodidad con la sintaxis. No hay prácticamente motivos tecnológicos sobresalientes que inclinen la balanza hacia algún lenguaje en particular, al menos entre los ofrecidos por Microsoft. Todos utilizan el mismo runtime, todos utilizan el mismo conjunto de bibliotecas de la misma forma, no existen diferencias notorias de performance entre ellos, todos tienen la misma potencia y todos tienen la misma capacidad de acceso a los recursos y servicios que expone el .NET Framework. De hecho, al cargar y ejecutar un assembly el CLR no sabe en qué lenguaje de programación de alto nivel éste fue escrito, ya que lo que el recibe como entrada es código MSIL.


Comments