Há alguns meses iniciei a escrita de uma série de posts que tratam das mudanças pelas quais a tecnologia de desenvolvimento para web da Microsoft (o ASP.NET) está passando. Quando iniciei a escrita, falávamos de ASP.NET vNext. Agora a tecnologia já possui um nome – ASP.NET 5. Já foram três posts (eles podem ser lidos na íntegra aqui) que apresentam os aspectos iniciais sobre a tecnologia neste novo momento, portanto, recomendo fortemente a leitura se você não possui os conhecimentos equivalentes.
Hoje, usando Visual Studio 2015 Community, iremos criar um projeto ASP.NET MVC 6 com base na versão Beta 7 da framework ASP.NET 5. Não iremos implementar muitas coisas aqui. Isso porque nosso objetivo é, antes de qualquer coisa, entender a estrutura do novo projeto, já que mudanças importantes foram implementadas e entender os papéis de cada elemento dentro da nova estrutura.
Antes de qualquer coisa, para que você possa acompanhar os exemplos que irei apresentar aqui, se você não possui o Visual Studio 2015 instalado você deverá efetuar o download e instalação da IDE assim como o ASP.NET 5 Beta 7. Seguem os links:
- Visual Studio 2015 RTM: http://go.microsoft.com/fwlink/?LinkId=532606
- ASP.NET 5 Beta 7: http://go.microsoft.com/fwlink/?LinkId=623894
Criando o projeto
O processo de criação de um projeto ASP.NET 5 permanece o mesmo, ou seja, “File” > “New” > “Project…“. Na janela que se apresenta, selecione a opção “C#” > “Web” e “Web application“. Ao fazer isso, nomear seu projeto e clicar em “OK“, uma nova janela semelhante aquela apresentada pela Figura 1 será apresentada.
Figura 1. Selecionando o template de projeto adequado
Como é possível perceber, temos duas classes de templates. A parte superior da janela apresenta os templates ASP.NET 4.5.2 enquanto a parte inferior apresenta templates da versão 5 (em modo preview). A Figura apresenta a seleção que iremos utilizar, isto é, uma “Web Application” com o template “ASP.NET 5“.
Além desta seleção, cliquei no botão “Change authentication” e marquei a opção “No authentication“. Também desmarquei a opção “Host in the cloud” porque não tenho a intensão publicar a aplicação neste momento. Após isso, cliquei em “OK“.
Uma observação importante aqui (pelo menos até aqui) é o fato de que não existe mais uma segmentação em “Webforms”, “MVC”, etc. Na prática o que sabemos é que os webforms não deverão mais estar presentes na pilha de tecnologias web da Microsoft. Um projeto ASP.NET 5 deverá ser nativamente MVC.
A estrutura do projeto
Ao finalizar o processo anterior, o Visual Studio apresentará o ambiente de trabalho com a Solution Explorer preenchida com os arquivos do projeto, como é possível visualizar na Figura 2.
Figura 2. Estrutura do projeto ASP.NET 5
O projeto ASP.NET 5 traz uma série de mudanças em relação as versões anteriores. Como é possível perceber só por bater o olho na estrutura apresentada pela Figura 2, temos uma segmentação de dois diretórios dentro da solution – “Solution Items” e “src“. O primeiro traz dois arquivos em seu interior (“global.json” e “Nuget.Config”) enquanto o segundo agrupa arquivos do projeto ASP.NET em si.
Outro aspecto que podemos notar logo de início é o advento de um diretório especial chamado “wwwroot“. As presenças de arquivos que até então não eram padrão de projeto (“bower.json”, “config.json”, “gulpfile.js”, “hosting.ini”, “project.json”, “package.json” e “startup.json”), a adição de um novo diretório chamado “Dependencies” e a ausência dos famosos arquivos “Global.asax” e “Web.config” e o *.sln são outras mudanças que podemos perceber inicialmente.
Isso posto, vamos então entender de forma mais detalhada as funções de cada um dos novos elementos e o porque de alguns “membros” tão famosos não estarem mais presentes na nova estrutura de projeto.
Os novos arquivos estruturais
Conforme mencionamos anteriormente, uma série de novos arquivos foram adicionados ao projeto e como você já deve ter percebido, a estrutura interna (formato) deles é o JSON, que cada vez mais se consolida como uma estrutura de dados padrão na web, assim como XML e outras já são.
Entender a função e como manipular cada um destes arquivos é de suma importância para que seu projeto ASP.NET tenha sucesso. Por isso, dispensaremos algum tempo para detalhar cada um deles.
O arquivo “project.json”
O novo arquivo “project.json” é o responsável por determinar principalmente ações de dependências do lado do servidor (server side), mas não apenas isso. Aqui também encontram-se informações específicas do projeto. Através de seções internas específicas que discutiremos a seguir, o desenvolvedor pode determinar, por exemplo, quais são as dependências do projeto e já determinar em tempo de execução configurações específicas para cada uma delas ou apenas para algumas delas.
Figura 3. As seções internas do arquivo “project.json”
A Figura 3 apresenta as seções do arquivo project.json presente na Solution Explorer do projeto que criamos anteriormente. Como você pode notar, são 8 seções e cada uma delas impacta na forma como a aplicação web irá se comportar no servidor web (elas estão em ordem alfabética porque o Visual Studio 2015 organizou pra mim 🙂 ).
Vamos então a mais detalhes sobre cada uma delas.
- commands: um dos grandes objetivos dos novos projetos ASP.NET é oferecer um suporte robusto para operações via linha de comando. Através da seção commands o desenvolvedor poderá determinar, por instância no ambiente de host (Azure Cloud Service, por exemplo), qual a configuração correta para determinado(s) componente(s) especificado(s) como dependência(s). A Figura 4 apresenta um exemplo disso. No exemplo, estamos dizendo que a configuração do ambiente de host deverá ser aquela determinada no arquivo “hosting.ini”.
Figura 4. Determinando o comportamento do web server via “command”
- dependencies: como você deve imaginar, a seção dependencies nos permite adicionar dependências das quais nosso projeto depende para funcionar de forma adequada. Vale lembrar que estamos falando de dependências de server side. Você pode determinar versões de forma manual (editanto este arquivo) ou via Nuget (o que for feito por lá – nuget – será refletido nesta seção). O diretório “References” irá refletir visualmente as dependências adicionadas. Veja a Figura 5 a seguir.
Figura 5. Referências adicionadas sendo refletidas na pasta “References”
- exclude e publishExclude: estas cláusulas permitem ao desenvolvedor especificar arquivos, diretórios e partes do projeto que deverão ser desconsiderados em dois momentos distintos: build e publish. O primeiro (exclude) refere-se ao build enquanto o segundo, refere-se aos bundles na publicação. A Figura 6 apresenta arquivos, diretórios e alguns outros elementos que serão excluídos apropriadamente do projeto.
Figura 6. Excluindo arquivos e diretórios via diretivas “exclude” e “publishExclude”
- frameworks: aqui podemos especificar o(s) destino(s), em termos de framework, de nossa aplicação, ou seja, se você quer que esta aplicação funcione com todos os recursos da .NET framework? aponte-a para “dnx451”. Gostaria de ver esta aplicação funcionando apenas com o .NET Core? Aponte-a para “dnxcore50”. Ao fazer isso, você estará dizendo ao ambiente de execução “que recursos ele deve ter em mãos” para executar sua aplicação. Além disso, as referências serão baixadas tanto para um framework, quanto para outro (note que, na Figura 5, temos as mesmas dependências para .NET full (DNX 4.5.1) e para .NET Core 5.0 (DNX Core 5.0). A Figura 7 apresenta a referência para ambas as frameworks.
Figura 7. Determinando as frameworks de destino da aplicação
- scripts: esta seção dá ao desenvolvedor o poder de especificar quando determinados scripts que atuam como “automatizadores de build” deverão ser executados. NPM e Bower (já existentes de forma nativa no projeto) são exemplos destes automatizadores. No Visual Studio 2015 é possível determinar quando estes automatizadores serão executados (antes ou depois de determinado evento). No exemplo apresentado pela Figura 8, antes da publicação (cláusula “prepublish”) estamos determinando que sejam instaladas dependências de client side via NPM e Bower (“npm install” e “bower install”). A Figura 8 apresenta a declaração de valores para esta seção.
Figura 8. Determinando o momento da instalação dos componentes através da cláusula “scripts”
- version: apenas um metadado sobre o projeto. Por padrão, o valor setado é 1.0.0-*. Além de version, você pode especificar mais metadados, como: author e description.
- webroot: esta é a cláusula que determina qual é o diretório base da aplicação. O runtime do ASP.NET 5 irá buscar informações sobre o projeto através da leitura desta seção. Em nosso caso, temos o valor padrão setado, “wwwroot”.
O arquivo “global.json”
Dentro do diretório “Solution Items” existe um arquivo bem importante para a nova estrutura de solution de projetos ASP.NET 5 – o “global.json”. Ele é o responsável pela configuração da solução como um todo (lembre-se, não temos mais os arquivos *.sln) e não apenas do projeto web. Em seu interior temos duas seções apenas: “projects” e “sdk”. A Figura 9 apresenta a estrutura do arquivo global.json.
Figura 9. Estrutura básica de um arquivo global.json
- projects: nesta cláusula apontamos os diretórios que possuem código fonte. “src” é por padrão a pasta onde estão hospedados controllers, repositórios, etc. e “test” é o diretório padrão onde se encontram fontes de testes. Isso pode ser modificado de acordo com a necessidade.
- sdk: a propriedade sdk nos permite determinar a versão do DNX que será utilizada. A pergunta que fica é: Mas porque isso é feito aqui ao invés de no arquivo “project.json”? A resposta é simples: para evitar que diferentes projetos dentro de uma mesma solution façam referência a diferentes versões da framework.
“bower”, “npm” e “gulp”
Bower é um famoso gerenciador de dependências de frameworks client side para aplicações web. Agora, o Visual Studio oferece amplo suporte para a utilização do Bower (e também NPM, que é outro gerenciador de dependências client side) nos projetos ASP.NET 5.
Tanto Bower quanto NPM atuam como automatizadores de builds, resolvendo dependências de client side antes ou depois de algum evento específico, conforme vimos na configuração do arquivo project.json.
Se expandirmos o diretório “Dependencies”, iremos encontrar em seu interior dois subdiretórios: “Bower” e “npm”. Expandindo os dois, encontraremos as frameworks que estão sendo gerenciadas por cada um deles. A pergunta que você deve estar se fazendo é: mas como essa gestão é realizada?
Se abrirmos o documento “bower.json” veremos que toda a especificação de chamadas já se encontra em seu interior (ver Figura 10).
Figura 10. Relação de frameworks declaradas com frameworks baixadas
Quando determinamos no arquivo “project.json” que em tempo de “prepublish” bower e npm deveriam instalar as dependências, determinamos que indiretamente (através da execução do Gulp, arquivo “gulpfile.js”) o Bower lesse “bower.json” e baixasse as dependências lá declaradas. A seta vermelha na Figura 10 indica que o resultado desse movimento pode ser visualizado nos diretórios bower e npm.
Os arquivos físicos das frameworks gerenciadas pelo Bower e pelo npm são baixados na pasta “lib”, dentro de “wwwroot”.
O arquivo “config.json”
Nas versões anteriores dos projetos ASP.NET, toda configuração administrativa da aplicação era armazenada em arquivos XML como web.config e outros.
A partir de agora, tais informações serão hospedadas em um tipo especial de arquivo desenhado pra armazenar informações deste tipo. O arquivo ao qual me refiro é o “config.json”. Com ele, podemos criar modelos mais ricos de configuração utilizando objetos inclusive ou ainda, entradas que fazem referências a outras entradas, como é o caso apresentado pela Figura 11.
Figura 11. Exemplo de entradas no config.json
É importante observar que, muito embora o formato JSON seja o mais apropriado para se trabalhar neste novo modelo de projeto ASP.NET, você não está limitado a ele. Arquivos XML e ini também são suportados (mas não recomendados 😉 ). Além disso, você poderá ter quantos arquivos de configuração quiser. Basta referência-los no arquivo “Startup.cs” (conforme apresenta a Listagem 1) que tudo deverá funcionar adequadamente.
Outra observação importante está relacionada ao nome. “config.json” é uma convenção mas não uma regra. Se você quiser criar outros arquivos de configuração e nomeá-los de acordo com sua necessidade, não há qualquer problema. Mais uma vez, basta registrar tais arquivos no “Startup.cs”.
O arquivo “Startup.cs”
Com o objetivo de entregar uma aplicação web mais leve (este é um requisito da web moderna), aplicações ASP.NET 5 devem ser construídas de maneira modular, de forma que apenas recursos que serão utilizados pela mesma sejam importados para seu contexto (pagar apenas pelo que usar).
Assim, para atingir este objetivo, a Microsoft trouxe a possibilidade de que o pipeline de execução da aplicação seja manipulado pelo desenvolvedor, de modo que ele possa trazer ao contexto da web app em momento oportuno, apenas os recursos necessários.
O arquivo “Startup.cs” é o elemento físico que armazena toda a configuração de pipeline das aplicações ASP.NET. Para que esta ideia de pipeline fique mais clara, considere a Figura 12.
Figura 12. Pipeline de execução de uma aplicação ASP.NET 5
Toda requisição que é processada por uma aplicação ASP.NET segue um fluxo de execução interno. Este fluxo é definido pela camada de middleware. Então note, podemos determinar que determinados recursos da aplicação web somente serão disponibilizados para usuários autenticados no sistema (middleware 1 – autenticação). Se o usuário estiver logado, libera recursos solicitados, senão, joga para fora do sistema e exibe uma mensagem de erro (middleware 2 – arquivos estáticos de erro). Veja a Figura 13 em outro esquema visual.
Figura 13. Pipeline em um outro esquema visual
Ou seja, a construção deste pipeline é determinada pelos middlewares da aplicação e estes middlewares são definidos dentro do método “Configure” na classe “Startup”.
Quando a aplicação ASP.NET 5 é iniciada, o método “Configure” da classe “Startup” é chamado e então o pipeline é montado em tempo de execução. Os método construtor da classe “Startup” tem a função de registrar elementos de configuração da aplicação. Já o método “ConfigureServices” é utilizado para determinar quais serviços estarão disponíveis na aplicação. Por exemplo: EntityFramework, MVC, SQL Server, etc.
Por hoje é só. No próximo post da série vamos iniciar a construção de uma aplicação simples que utiliza MVC e banco de dados para solidificar mais os conceitos apresentados neste post.
Não esqueça de deixar seu comentário, crítica ou sugestão.
Facebook
Twitter
Instagram
LinkedIn
RSS