Compartir a través de


El programador políglota

Introducción a Oak: un enfoque diferente

Ted Neward

Ted NewardTal como dije la vez pasada, el proyecto Oak es un marco web que incorpora aspectos y métodos dinámicos que son comunes en los marcos basados en lenguajes más dinámicos como Ruby on Rails o cualquiera de los abundantes marcos web MVC en Node.js, como Express o Tower. Como está basado en Microsoft .NET Framework y usa partes del tiempo de ejecución de lenguaje dinámico (DLR) de C#, Oak sigue un camino bastante diferente para desarrollar aplicaciones web al que emplea el desarrollador ASP.NET MVC tradicional. Por esta razón, como vimos la última vez, obtener las piezas necesarias para desarrollar con Oak es un poco más sofisticado que descargarlas simplemente con NuGet.

Suponiendo que leyó la columna anterior (msdn.microsoft.com/magazine/dn451446), descargó las partes, las instaló, inició el sidekick de compilación continua y logró que la compilación inicial se ejecutara en su máquina (en IIS Express, en el puerto 3000, como recordará), llegó el momento de comenzar a desarrollar con Oak.

Inicialización

Si no se está ejecutando en su equipo, ejecute “rake” y “rake server” en un símbolo del sistema, para asegurarse de que todo esté como Dios manda. Lugo inicie “sidekick” (si no lo está ya) y abra un explorador web en localhost:3000, tal como se ilustra en la figura 1.

Oak Project Help Window
Figura 1 Ventana de ayuda del proyecto Oak

Tal como lo implica el tutorial resultante, hay una especie de guía mediante rutas de navegación para aprender Oak. Antes de comenzar, eso sí, eche una mirada a la estructura del proyecto, que se muestra en la figura 2.

Oak Project Structure in Visual Studio Solution Explorer
Figura 2 Estructura del proyecto Oak en el Explorador de soluciones de Visual Studio

El proyecto semilla consta de dos proyectos: el proyecto ASP.NET MVC y el proyecto con las pruebas para la solución. El proyecto MVC es una aplicación ASP.NET MVC tradicional con la carpeta “Oak” adicional que contiene los archivos de código fuente que componen las partes del proyecto que pertenecen a Oak. De este modo, resulta absolutamente trivial recorrer las partes de Oak del código durante la depuración y, fiel al espíritu de todos los proyectos de código abierto, también se pueden realizar modificaciones locales cuando y si es que fuera necesario. Actualmente, el proyecto no tiene modelos, cuenta con tres controladores y solo un par de vistas. Más importante, ya no hay gran cosa en términos de código, la primera solicitud que enviamos al extremo arroja un error que indica que no existe ninguna vista “Index.cshtml” (o algo similar). El sistema de arranque de Oak sugiere dos pasos. Primero debemos crear dos tipos nuevos: Blog y Blogs, una colección de instancias de Blog. Al llamar la clase “Blogs”, obtenemos un acceso fácil basado en convenciones a la tabla Blogs en la base de datos:

public class Blogs : DynamicRepository
{
}
// This is a dynamic entity that represents the blog
public class Blog : DynamicModel
{
  public Blog() { }
  public Blog(object dto) : base(dto) { }
}

Segundo, HomeController requiere de algunos cambios para poder responder a diferentes solicitudes HTTP, tal como se ilustra en la figura 3.

Figura 3 Respuesta ante diferentes solicitudes HTTP

public class HomeController : Controller
{
  // Initialize the blog
  Blogs blogs = new Blogs();
  public ActionResult Index()
  {
    // Return all blogs from the database
    ViewBag.Blogs = blogs.All();
    return View();
  }
  // Controller action to save a blog
  [HttpPost]
  public ActionResult Index(dynamic @params)
  {
    dynamic blog = new Blog(@params);

Gran parte de esto resultará familiar para los desarrolladores de ASP.NET. Lo que es notablemente diferente es que el tipo siempre es el tipo dynamic de C#, en vez de instancias de Blog o de Blogs. El tipo Blog mismo no tiene campos ni propiedades. Del mismo modo, el tipo Blogs —un agregado de instancias de Blog— no declara ninguna código para insertar, eliminar, enumerar, reemplazar ni realizar ninguna de las operaciones que comúnmente se asocian con las colecciones.

Este poder proviene en gran medida de la biblioteca Gemini basada en dynamic, una parte central del proyecto Oak (y el tema de mi columna de agosto de 2013, “Dinamícese con la biblioteca Gemini”, en msdn.microsoft.com/magazine/dn342877). Blog extiende la clase base DynamicModel, lo que significa esencialmente que podemos comenzar a programar sin tener que definir un modelo antes. Cualquier campo al que hagamos referencia en cualquier instancia de Blog se encuentra allí, incluso si nunca hicimos referencia a ella antes. Este es el poder de la programación dinámica. Del mismo modo, Blogs es un DynamicRepository. Y como tal, ya sabe cómo almacenar y manipular los objetos DynamicModel.

Más interesante aún es que desde el primer momento, Oak sabe cómo almacenar las instancias de Blog en una tabla SQL (llamada, como es de esperar, “Blogs”). No solo creará el esquema de la base de datos la primera vez que esta se use, sino que también puede “inicializar” la base de datos con todos los datos de inicialización que el sistema pueda requerir.

Cuando construimos una instancia de Blog, esta acepta un objeto dinámico como parámetro. El constructor de la clase base sabe cómo recorrer cualquiera de los campos/propiedades definidos en forma dinámica en ese proyecto. Del mismo modo, la instancia de Blogs también sabe cómo iterar por todos los campos/propiedades definidos en forma dinámica en una instancia de Blog. Las almacena en la base de datos (en la llamada a blog.Insert). También sabe cómo recuperar una instancia de Blog de la base de datos por medio del campo BlogId. De todo esto se encarga el código de la figura 3; no hace falta código adicional, al menos por el momento. (Hay otras cosas que también van aquí, pero por el momento, todo funciona tal cual.)

Por cierto, si tiene curiosidad por saber qué es el operador @, recuerde que params es una palabra reservada en C#. Para usarlo como nombre para un parámetro, tenemos que anteponerle @ para indicarle al compilador de C# que no lo trate como palabra clave.

Una vez que modificamos HomeController.cs, el siguiente paso es crear una vista aceptable, Index.cshtml, en la carpeta Home bajo la carpeta Views. Esto presentará los resultados del trabajo del controlador, tal como se aprecia en la figura 4.

Figura 4 Creación de la vista

@{
  ViewBag.Title = "Index";
}
<h2>Hello World</h2>
<div>

Si esta página apareció correctamente, entonces usted va por buen camino. Siga adelante y cree un blog (trate de crear blogs con nombres duplicados).

</div>
<br />
@using (Html.BeginForm()) 
{
  @Html.TextBox("Name")
  <input type="submit" value="create" />
}
@foreach (var blog in ViewBag.Blogs)
{
  <div>
    <pre>@blog</pre>
    <br />
    <div>
Almost there, you have comments listing; let's try to add one.
    </div>
    <br />
  </div>
}

Superficialmente, la vista no es una vista ASP.NET cualquiera. Nuevamente entra en juego la naturaleza dinámica del sistema. Ninguna instancia de Blog definió un campo Name en el tipo Blog; sin embargo, cuando se envía el formulario en la parte superior de la vista, se pasa un parámetro “name=...” a HomeController. Este controlador luego pasará ese par nombre/valor en la variable @params que se usa para inicializar una instancia de Blog. Sin ningún trabajo adicional por nuestra parte, la instancia de Blog ahora contiene un campo/propiedad Name.

Continuidad continua

Por cierto, si juega la versión doméstica del juego y guardó esos archivos, verá que ocurrió algo interesante (ver figura 5).

Growl Notification Showing the Build Succeeded
Figura 5 Notificación de Growl que indica la compilación correcta

Primero que nada, apareció una notificación en la esquina inferior derecha. Esto es obra de Growl. Nos entrega la notificación con la luz verde que indica que la compilación iniciada por la aplicación sidekick que iniciamos previamente terminó correctamente. Si por alguna razón se genera un error, el gráfico en el lado izquierdo de la ventana de notificación será rojo, y la consola mostrará la notificación. Segundo, si se fija en la ventana de la consola en la que se ejecuta sidekick, verá qué es lo que ocurrió. El monitor del sistema de archivos en el directorio Blog registró que un archivo de código fuente cambió (porque lo guardamos). Sidekick lo interpretó como indicación para recompilar el proyecto.

Suponiendo que los archivos se guardaron y que el código está correcto, al presionar localhost:3000 nuevamente aparece el resultado nuevo, tal como se aprecia en la figura 6.

Oak Cannot Make Bricks Without Clay
Figura 6 Oak No puede hacer ladrillos sin arcilla

Esta vez Oak trata de conectarse a una instancia activa de SQL Server para recuperar los datos de esa tabla (la tabla Blog). Esto es Oak tratando de administrar automáticamente las partes de la asignación relacional de objetos (ORM) del proyecto por nosotros; un tema en el que ahondaré la próxima vez.

Un estilo diferente

Como puede ver, usar Oak definitivamente implica un modo de desarrollo muy diferente. En ningún momento tuvo que hacer nada más complicado en Visual Studio que abrir un archivo, cambiar el contenido y guardar la versión nueva… y agregar un archivo nuevo al proyecto. En ningún momento tuvo que iniciar una compilación, ejecutarla desde dentro de Visual Studio ni abrir Server Explorer para crear tablas o iniciar algún script para SQL Server.

Todas esas cosas siguen estando disponibles, si llegara a necesitarlas. Nuevamente, Oak es solo una capa (y una bastante ligera) encima de la pila ASP.NET tradicional. Sin embargo, esta capa permite un nivel de desarrollo más rápido, con una productividad similar a otros entornos más dinámicos, sin perder ninguna de las características que tanto apreciamos del mundo de los lenguajes tipados en forma estática.

Hay más cosas que hacer con Oak, pero eso será tema de otra columna.

¡Que disfrute programando!

Ted Neward es el director de Neward & Associates LLC. Ha escrito más de 100 artículos y es autor y coautor de una docena de libros, incluido “Professional F# 2.0” (Wrox, 2010). Es un MVP de F# y orador en congresos en todo el mundo. Asesora y asiste como mentor con regularidad; puede encontrarlo en ted@tedneward.com si está interesado en que vaya a trabajar con su equipo o puede leer su blog en blogs.tedneward.com.

Gracias al siguiente experto técnico por su ayuda en la revisión de este artículo: Amir Rajan (creador del proyecto Oak)