Itens de configuração no ASP.NET 5: o que mudou em relação às versões anteriores?

Em Maio/2014 a Microsoft anunciaria durante o TechEd norte-americano uma grande novidade: tratava-se do ASP.NET vNext, uma plataforma remodelada para o desenvolvimento Web baseado no .NET Framework. Com uma forte ênfase na implementação de soluções voltadas a ambientes de cloud computing, esta evolução da tecnologia ASP.NET se destaca ainda por melhorias visando a obtenção de aplicações com uma maior performance em tempo de execução.

Já em Julho/2014 seria apresentada uma nova versão do Visual Studio (batizada de Visual Studio “14” CTP 1), já contemplando o suporte à construção de aplicações com o ASP.NET vNext.

Publiquei anteriormente um artigo sobre estas mudanças, detalhando resumidamente as principais melhorias trazidas pelo ASP.NET vNext e o Visual Studio “14”:

http://www.devmedia.com.br/novidades-do-asp-net-vnext-e-do-visual-studio/31166

Ambos os produtos passariam pelo lançamento de outros releases desde então. Novas notícias de grande impacto viriam à tona em meados de Novembro/2014, durante o evento chamado “Connect”:

→ O ASP.NET vNext foi rebatizado como “ASP.NET 5”;

→ Quanto ao Visual Studio “14”, o mesmo deu lugar ao “Visual Studio 2015 Preview”;

→ Houve o anúncio ainda do .NET Framework 2015, com a Microsoft disponibilizando o Core de sua plataforma de desenvolvimento como um projeto open source hospedado no GitHub.

Uma das principais modificações no novo ASP.NET foi a remoção do namespace System.Web, em um avanço visando a implementação de soluções Web mais leves e com uma melhor performance. A própria forma como um projeto se encontra estruturado passou por alterações: enquanto em versões anteriores os arquivos de configuração de um projeto eram documentos XML (geralmente com a extensão “.config”), com o ASP.NET 5 houve uma mudança de direção priorizando o uso do formato JSON.

A meta deste artigo é detalhar a nova estrutura de itens de configuração em projetos ASP.NET 5. Para isto será criada uma aplicação MVC com o Visual Studio 2015, a fim de demonstrar como ficaram os arquivos de configuração e de que maneira os mesmos podem ser manipulados.

Criando uma aplicação MVC para testes envolvendo configurações

Para implementar a aplicação de testes demonstrada nesta seção foram utilizados os seguintes recursos:

→ O Microsoft Visual Studio 2015 Preview como IDE de desenvolvimento;

→ O .NET Framework 4.5.3;

→ O framework ASP.NET 5 para a criação de uma Web Application.

O projeto TesteASPNETvNext será do tipo “ASP.NET Web Application” (Imagem 1), sendo gerado a partir da seleção do template “ASP.NET 5 Starter Web” (Imagem 2).

Imagem 1. Criando uma ASP.NET Web Aplication no Visual Studio 2015

Imagem 1. Criando uma ASP.NET Web Aplication no Visual Studio 2015

Imagem 2. Selecionando o template para a criação de uma aplicação ASP.NET 5

Imagem 2. Selecionando o template para a criação de uma aplicação ASP.NET 5

Analisando a estrutura do projeto criado (Imagem 3) nota-se a existência de três arquivos:

→ config.json: itens de configuração de um projeto. Este documento é o equivalente ao Web.config, presente em versões anteriores do ASP.NET;

→ package.json: aqui podem ser declarados packages dos quais um projeto depende (em substituição ao arquivo package.config);

→ project.json: contém definições e configurações gerais de uma aplicação. Este documento substitui os arquivos com extensão .csproj (no caso de uma aplicação baseada no uso de C#).

Imagem 3. Estrutura de um projeto ASP.NET 5

Imagem 3. Estrutura de um projeto ASP.NET 5

Na Imagem 4 é possível observar o conteúdo (no formato JSON) do arquivo project.json:

Imagem 4. Conteúdo do arquivo project.json

Imagem 4. Conteúdo do arquivo project.json

Como não é difícil de se imaginar, a manipulação de itens de configuração também passou por uma grande reformulação. Em versões anteriores do ASP.NET este mecanismo envolvia o uso de declarações XML no arquivo Web.config, com a leitura dos valores correspondentes acontecendo por meio da classe ConfigurationManager.

Com o ASP.NET 5 o Web.config daria lugar ao arquivo config.json, conforme já mencionado anteriormente. Além disso o tipo ConfigurationManager foi substituído pela interface IConfiguration (esta última pertencente ao namespace Microsoft.Framework.ConfigurationModel).

Embora o arquivo config.json represente o padrão assumido para projetos ASP.NET 5, as configurações vinculadas a um projeto podem possuir outras origens. A especificação de quais arquivos contêm itens de configuração a serem utilizados por uma aplicação acontece na classe Startup (que equivale ao antigo Global.asax). Na Listagem 1 está o código que define este tipo:

→ A propriedade Configuration armazenará uma instância de uma classe que deriva de IConfiguration;

→ Será no construtor do tipo Startup que uma referência da classe Configuration (namespace Microsoft.Framework.ConfigurationModel) será associada à propriedade de mesmo nome. Nota-se neste ponto o uso dos métodos AddJsonFile (adicionando o conteúdo do arquivo config.json às configurações disponíveis) e AddEnvironmentVariables (para o acesso a variáveis de ambiente). Outros arquivos .json com itens de configuração poderiam ser incluídos opcionalmente, assim como arquivos com a extensão .ini (através da operação AddIniFile);

→ Já o método ConfigureServices será utilizado para a configuração do mecanismo de injeção de dependências do ASP.NET MVC. Esta operação recebe como parâmetro uma instância do tipo IServiceCollection (namespace Microsoft.Framework.DependencyInjection), a qual será empregada no mapeamento de dependências entre tipos básicos (como interfaces) e implementações concretas destes últimos. Para o exemplo aqui abordado será necessário alterar o método ConfigureServices, de forma que a instância de IServiceCollection seja capaz de mapear todas as ocorrências de IConfiguration para a instância associada à propriedade Configuration. O uso do método AddSingleton faz com que uma única de instância de IConfiguration seja utilizada na resolução de todas as dependências encontradas ao longo de uma aplicação, sendo este um exemplo prático de aplicação do pattern Singleton.

Listagem 1: Classe Startup

using System;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Diagnostics;
using Microsoft.AspNet.Diagnostics.Entity;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.Logging;
using Microsoft.Framework.Logging.Console;
using TesteASPNET5Config.Models;

namespace TesteASPNET5Config
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            Configuration = new Configuration()
                .AddJsonFile("config.json")
                .AddEnvironmentVariables();
        }

        public IConfiguration Configuration { get; set; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IConfiguration>(_ => Configuration);

            ...
        }

        ...
    }
}

OBSERVAÇÃO IMPORTANTE: o suporte à injeção de dependências também foi remodelado no ASP.NET 5. Em versões anteriores a opção por este tipo de prática implicava, obrigatoriamente, no uso de um container DI como Unity, NInject ou Spring.NET, dentre outras opções possíveis. Embora esta alternativa ainda esteja disponível, a nova versão da tecnologia ASP.NET também incorpora um mecanismo nativo para injeção de dependências.

O conteúdo do arquivo config.json está detalhado na Listagem 2. Duas propriedades (“Configuracao1” e “Configuracao2”) foram definidas, sendo que ambas fazem parte de uma seção chamada “Teste”. Diferentemente de um arquivo Web.config tradicional (em que a adoção de uma estrutura mais complexa podia envolver até mesmo a implementação de um assembly específico), não existe mais um esquema rígido para a declaração de itens de configuração. Diferentes níveis podem ser incluídos na especificação de propriedades, desde que se respeite o formato básico de um documento JSON.

Listagem 2: Conteúdo do arquivo config.json

{
    "Teste": {
        "Configuracao1":  "Valor Configuração 1",
        "Configuracao2":  "Valor Configuração 2"
    }
}

O próximo passo será a realização de ajustes na implementação do Controller HomeController (Listagem 3):

→ Uma propriedade baseada na interface IConfiguration precisará ser especificada na definição do tipo HomeController, com o intuito de possibilitar o acesso aos itens de configuração dentro deste Controller;

→ Um construtor também deverá ser declarado para a classe HomeController. Será através dessa estrutura que o mecanismo de injeção de injeção de dependências do ASP.NET irá resolver a dependência de IConfiguration (o construtor de HomeController será automaticamente invocado pelo container DI). Até o presente momento (Novembro/2014) o ASP.NET 5 permite aplicar técnicas de injeção apenas através do uso de construtores públicos (não há ainda suporte nativo para o uso deste tipo de prática com propriedades públicas, por exemplo);

→ Na Action Index é possível observar que o valor de “Configuracao1” está sendo associado à propriedade ViewBag, através de uma chamada ao método Get da instância associada à propriedade Configuration. O acesso a uma propriedade definida no arquivo config.json requer o uso do caracter “:” (dois pontos), de forma a separar cada nível que antecede a configuração em questão.

Listagem 3: Classe HomeController

using Microsoft.Framework.ConfigurationModel;
using Microsoft.AspNet.Mvc;

namespace TesteASPNET5Config.Controllers
{
    public class HomeController : Controller
    {
        public IConfiguration Configuration { get; set; }

        public HomeController(IConfiguration config)
        {
            this.Configuration = config;
        }

        public IActionResult Index()
        {
            ViewBag.Config1 =
                Configuration.Get("Teste:Configuracao1");
            return View();
        }

        ...

    }
}

A View Index.cshtml também será modificada (Listagem 4), a fim de exibir os valores dos itens de configuração definidos no arquivo config.json:

→ No início desta View a cláusula “@using” está referenciando o namespace Microsoft.Framework.ConfigurationModel;

→ Já a cláusula “@inject” será utilizada para resolver a dependência representada pela variável “config”, de forma que se associe a esta referência a instância do tipo IConfiguration gerada durante a inicialização da aplicação;

→ O valor do item “Configuracao1” encontra-se acessível a partir do objeto ViewBag (o mesmo foi preenchido durante a execução da Action Index), ao passo que o conteúdo de “Configuracao2” será obtido por meio da referência vinculada à variável “config”.

Listagem 4: Index.cshtml

@using Microsoft.Framework.ConfigurationModel
@inject IConfiguration config

<div class="jumbotron">
    <h1>ASP.NET 5</h1>
    <p class="lead">Exemplo de aplicação MVC baseada no ASP.NET 5.</p>
    <p><a href="http://asp.net/vnext"
          class="btn btn-primary btn-lg">Saiba mais &raquo;</a></p>
</div>

<h2>Teste envolvendo o uso de configurações no ASP.NET 5</h2>

<br /><br />

<div style="font-size: 20px; height: 150px;">
    <b>Configuracao1:</b> @ViewBag.Config1
    <br />
    <b>Configuracao2:</b> @config.Get("Teste:Configuracao2")
</div>

Por fim, será necessário executar o projeto TesteASPNET5Config a partir do Visual Studio 2015. Aparecerá então a tela inicial desta aplicação (Imagem 5), na qual constarão os valores das configurações declaradas no arquivo config.json.

Imagem 5. Executando o projeto de testes

Imagem 5. Executando o projeto de testes

Conclusão

Conforme demonstrado ao longo deste artigo, o ASP.NET 5 foi concebido com um novo mecanismo para a manipulação de itens de configuração. A adoção do formato JSON procurou flexibilizar o uso de arquivos deste tipo, através de um modelo menos rígido e que pode ser customizado sem maiores dificuldades.

Espero que o conteúdo apresentado neste post possa ser útil no seu dia-a-dia.

Até uma próxima oportunidade!

Renato Groffe – Consultor em TI, MCTS
http://rgroffe.wordpress.com/

Referências

ASP.NET vNext
http://www.asp.net/vnext

ASP.NET vNext Moving Parts: IConfiguration
http://whereslou.com/2014/05/23/asp-net-vnext-moving-parts-iconfiguration/

Dependency Injection in ASP.NET vNext
http://blogs.msdn.com/b/webdev/archive/2014/06/17/dependency-injection-in-asp-net-vnext.aspx

Visual Studio 2015 Downloads
http://www.visualstudio.com/en-us/downloads/visual-studio-2015-downloads-vs.aspx

Comentarios

comentarios