O programador

Introdução ao Oak: uma abordagem diferente

Ted Neward

Ted Neward
Como discutido da última vez, o projeto Oak é uma estrutura Web que incorpora aspectos dinâmicos e abordagens comuns a mais estruturas baseadas em linguagem dinâmica (como Ruby on Rails ou qualquer das diversas estruturas Web MVC em Node.js, como Express ou Tower). Como é baseado no Microsoft .NET Framework e usa partes dinâmicas e do DLR (Dynamic Language Runtime, Tempo de execução de linguagem dinâmica) do C#, o Oak usa uma abordagem bastante diferente no desenvolvimento de aplicativos Web das usadas pelo desenvolvedor tradicional de ASP.NET MVC. Por essa razão, como descoberto da última vez, ter os bits necessários para trabalhar no desenvolvimento do Oak é um pouco mais sofisticado que simplesmente puxá-lo por meio do NuGet.

Supondo que você tenha lido a coluna anterior (msdn.microsoft.com/magazine/dn451446), baixado e instalado os bits, dado início ao auxiliar contínuo de compilação e colocado a compilação inicial em execução em seu computador (no IIS Express, na porta 3000, como você se lembra), é hora de começar a trabalhar em desenvolvimento no Oak.

Iniciando

Se não estiver em execução em sua caixa, faça uma “limpeza” e um “limpar servidor” de um prompt de comando, apenas para ter certeza que tudo esteja limpo. Então, inicie o “auxiliar” (se ainda não estiver em execução) e abra um navegador para localhost:3000, como mostrado na Figura 1.

Oak Project Help Window
Figura 1 Janela de ajuda do projeto Oak

Como o tutorial resultante indica, há uma espécie de passo a passo no estilo de trilha para aprender o Oak. No entanto, antes de iniciarmos, dê uma olhada rápida na estrutura do projeto, mostrado na Figura 2.

Oak Project Structure in Visual Studio Solution Explorer
Figura 2 Estrutura do projeto Oak no Gerenciador de Soluções do Visual Studio

O projeto inicial consiste em dois projetos: o projeto ASP.NET MVC e o projeto com os testes para a solução. O projeto MVC é uma aplicativo ASP.NET MVC tradicional, com a pasta “Oak” adicionada contendo os arquivos de origem que formam as partes Oak do projeto. Isso torna absolutamente trivial percorrer as partes Oak do código durante a depuração e, no espírito de todos os projetos de software livre, também permite modificações locais, se e quando necessárias. Atualmente, o projeto não tem modelos, três controladores e apenas algumas exibições. Mais importante, como não há muito código aqui, a primeira solicitação para o ponto de extremidade resulta em um erro de que nenhuma exibição “Index.cshtml” (ou similar) existe. O bootstrapper do Oak sugere duas etapas. Primeira, você precisa criar dois novos tipos: Blog e Blogs, uma coleção de instâncias de Blog. Chamar a classe de “Blogs” lhe dá acesso fácil e baseado em convenção à tabela Blogs no banco de dados.

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, o HomeController precisa de algumas alterações para poder responder a diferentes solicitações HTTP enviadas, como mostrado na Figura 3.

Figura 3 Respondendo a diferentes solicitações 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);

Muito disso será familiar para desenvolvedores do ASP.NET: O que é bastante diferente é que tudo é tipado como o tipo dinâmico do C#, não como instâncias de Blog ou Blogs. O próprio tipo Blog não tem nenhum campo ou propriedade. O tipo Blog—um agregado de instâncias de Blog—da mesma forma não tem código declarado nele para inserir, remover, listar, substituir ou fazer qualquer uma das outras operações normalmente associadas a coleções.

Muito desse poder vem da biblioteca Gemini baseada em dinâmica, uma parte central do projeto Oak (e o assunto de minha coluna de agosto de 2013, “Tornando-se dinâmico com a biblioteca Gemini” em msdn.microsoft.com/magazine/dn342877). Blog amplia a classe base DynamicModel, o que basicamente significa que você pode programar nela sem ter de definir o modelo de início. Qualquer campo que você referenciar em qualquer instância de Blog específica estará lá, mesmo que nunca o tenha referenciado antes. Essa é o poder da programação dinâmica. Da mesma forma, Blogs é um DynamicRepository. Como tal, ele já sabe como armazenar e manipular objetos DynamicModel.

Ainda mais interessante é que de imediato o Oak sabe como armazenar instâncias de Blog em uma tabela SQL (chamada, sem surpresa, “Blogs”). Ele não apenas criará o esquema de banco de dados no primeiro uso, mas ele poderá “iniciar” o banco de dados com qualquer dado de inicialização que o sistema possa precisar.

Ao construir uma instância de Blog, ele assume um objeto dinâmico como parâmetro. O construtor da classe base sabe como percorrer qualquer dos campos/propriedades definidos dinamicamente nesse objeto. Da mesma forma, a instância de Blogs também saberá como iterar por todos os campos/propriedades definidos dinamicamente de uma instância de Blog. Ele as armazenará no banco de dados (na chamada para blog.Insert). Ele também sabe como recuperar uma instância de Blog do banco de dados por meio do campo BlogId. Tudo isso é habilitado pelo código da Figura 3; nenhum código de modelo adicional é necessário—pelo menos, ainda não. (Há outras coisas que você irá desejar aí, mas no momento, tudo funciona bem.)

A propósito, se estiver imaginando o que o operador @ é, lembre-se de que params é, na verdade, uma palavra reservada no C#. Para usá-lo como um nome de parâmetro aceitável, coloque o prefixo @ para dizer ao compilador do C# para não tratá-lo como uma palavra-chave.

Tendo modificado HomeController.cs, a próxima etapa é criar uma exibição aceitável, Index.cshtml, em uma pasta Home sob a pasta Views. Isso exibirá os resultados do trabalho do controlado, conforme mostrado na Figura 4.

Figura 4 Criando a exibição

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

Se essa página apareceu com sucesso, você está indo bem. Continue e crie um blog (tente criar blogs com nomes 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>
}

À primeira vista, a exibição não é simplesmente outra exibição ASP.NET. Novamente, a natureza dinâmica do sistema entra em campo. Nenhuma instância de Blog definiu um campo Name no tipo Blog, no entanto, quando o formulário no alto da exibição for enviado, um parâmetro “name=...” será passado para o HomeController. Esse controlador então passará esse par nome/valor na variável @params usada para inicializar uma instância de Blog. Sem qualquer trabalho adicional de sua parte, a instância de Blog agora tem um campo/propriedade Name nela.

Continuidade contínua

A propósito, se estiver jogando com a versão home desse jogo e salvou esses arquivos, você verá que algo interessante aconteceu (consulte a Figura 5).

Growl Notification Showing the Build Succeeded
Figura 5 Uma notificação do Growl mostrando que a compilação teve sucesso

Em primeiro lugar, a notificação foi exibida no canto inferior direito. Isso é o Growl trabalhando. Ele está lhe dando a notificação de luz verde de que a compilação iniciada pelo aplicativo auxiliar iniciado anteriormente foi bem-sucedida. Se falhar por alguma razão, o elemento gráfico à esquerda da janela de notificação ficará vermelho, e a saída do console será exibida na notificação. Segundo, se você olhar na janela do console em que o auxiliar está em execução, estará aparente o que aconteceu. O inspetor do sistema de arquivos no diretório Blog registrou que um arquivo de origem foi alterado (porque você o salvou). O auxiliar assumiu isso como uma indicação para recompilar o projeto.

Supondo que os arquivos estejam salvos e que o código esteja correto, acessar localhost:3000 novamente leva ao novo resultado, mostrado na Figura 6.

Oak Cannot Make Bricks Without Clay
Figura 6 O Oak não pode fazer tijolos sem barro

Desta vez, o Oak está tentando se conectar a uma instância do SQL Server em execução para buscar qualquer dado da tabela (a tabela Blog). Esse é o Oak tentando automaticamente gerenciar as partes do mapeamento relacional de objeto (ORM) do projeto em seu nome. Irei me aprofundar mais nisso da próxima vez.

Um estilo diferente

Como pode ser visto, usar o Oak definitivamente envolve um estilo diferente de desenvolvimento. Em nenhum momento você teve de fazer algo mais complicado no Visual Studio do que abrir um arquivo, mudar seu conteúdo e salvar a nova versão—e adicionar um novo arquivo ao projeto. Você nunca teve de iniciar uma compilação, executá-la de dentro do Visual Studio ou abrir o Gerenciador de Servidores para criar tabelas ou iniciar scripts do SQL Server.

Todas essas coisas ainda estão disponíveis para você, caso apareça a necessidade. Novamente, o Oak é apenas uma camada (e uma bastante fina) em cima da pilha do ASP.NET tradicional. No entanto, essa camada permite um grau de rápido desenvolvimento e produtividade similar a outros ambientes mais dinâmicos, sem perder as coisas de que você gosta do mundo do tipo estático.

Há mais o que fazer com o Oak, mas ficará como assunto para uma próxima discussão.

Boa codificação.

Ted Neward -é o diretor da Neward & Associates LLC. Ele já escreveu mais de 100 artigos e é autor e coautor de dezenas de livros, incluindo “Professional F# 2.0” (Wrox, 2010). Ele é um MVP de F# e participa como palestrante em conferências em todo o mundo. Ele atua como consultor e mentor regularmente. Entre em contato com ele pelo email ted@tedneward.com se desejar que ele venha trabalhar com sua equipe ou leia seu blog em blogs.tedneward.com.

Agradecemos ao seguinte especialista técnico pela revisão deste artigo: Amir Rajan (criador do projeto Oak)