.NET

5 set, 2017

Novidades do ASP.NET Core 2.0

Publicidade

A última semana de agosto foi bastante agitada dentro da comunidade .NET, com o release do update 15.3 do Visual Studio 2017 e das versões 2.0 do .NET Core, do ASP.NET Core, do Entity Framework Core e do .NET Standard.

Os anúncios oficiais podem ser consultados nos seguintes links:

Hoje vou apresentar algumas das novidades do ASP.NET Core 2.0, além de orientações e exemplos envolvendo as mudanças trazidas por esta nova versão.

Instalação e novos templates

O ASP.NET Core 2.0 estará disponível para uso após a instalação do .NET Core 2.0, o qual conta com versões Windows, Linux, Mac e containers Docker: .NET Core 2.0

Ao executar o comando dotnet — version, deverá aparecer a versão 2.0.0, conforme indicado na imagem a seguir (esse teste aconteceu em uma janela do Terminal no Ubuntu 17.04):

Para utilizar o .NET Core 2.0, ASP.NET Core 2.0 e o .NET Standard 2.0 com o Visual Studio 2017, será necessário instalar também o Update 15.3desta IDE: Visual Studio Downloads.

As próximas imagens trazem os templates disponíveis para a criação de projetos baseados no .NET Core e no .NET Standard:

Templates do .NET Core no Visual Studio 2017 Update 15.3
Templates do .NET Standard

Ao selecionar ASP.NET Core Web Application, aparecerão os templates disponíveis para desenvolvimento Web:

  • As opções Empty (com o mínimo de recursos habilitados) e Web API (para APIs REST) seguem a mesma nomenclatura de versões anteriores;
  • Projetos do tipo Web Application (Model-View-Controller) referem-se a aplicações MVC convencionais, sendo anteriormente conhecidos apenas como Web Application (até o Update 15.2 do Visual Studio 2017);
  • Já o novo template Web Application emprega Razor Pages como estrutura básica para a geração de conteúdo em HTML. Este tipo de recurso será abordado em maiores detalhes na próxima seção;
  • Temos ainda novas alternativas para a criação de projetos baseados em Angular, React.js e React.js + Redux.

Nesta janela é possível definir ainda o uso do .NET Core ou do .NET Framework (este último restrito apenas a ambientes Windows) na geração de um novo projeto:

E também a versão do ASP.NET Core a ser empregada:

O .NET Core Command-Line Interface (CLI) já contemplará, após a instalação do .NET Core 2.0, as novas opções de templates:

Importante lembrar ainda que o Visual Studio Code é uma alternativa multiplataforma para desenvolvimento com ASP.NET Core 2.0, oferecendo suporte ao Windows, Mac e diversas distribuições Linux:

Desenvolvendo com ASP.NET Core 2.0 e Visual Studio Code no Ubuntu 17.04

Razor Pages

Razor Pages nada mais são do que páginas capazes de tratar diretamente uma requisição, sem depender de um Controller durante esse processo. Para criar uma aplicação deste tipo, deverá ser utilizado o template Web Application:

Na listagem a seguir, é possível observar uma View baseada neste novo recurso:

  • Uma Razor Page é identificada pela presença da diretiva @page no código de um arquivo Razor (extensão .cshtml);
  • Elementos de front-end como HTML Helpers, Tag Helpers e View Components podem ser utilizados aqui normalmente, da mesma que já acontecia em Views de aplicações MVC convencionais.
@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<h2>@TempData["Mensagem"]</h2>
<h3>Data atual: @DateTime.Now.ToString("dd/MM/yyyy")</h3>

Uma Razor Page conta ainda com uma classe derivada do tipo PageModel(namespace Microsoft.AspNetCore.Mvc.RazorPages). No método OnGet será possível o acesso a recursos como APIs REST e bancos de dados via código .NET:

using Microsoft.AspNetCore.Mvc.RazorPages;

namespace ExemploRazorPages.Pages
{
    public class IndexModel : PageModel
    {
        public void OnGet()
        {
            TempData["Mensagem"] = "Utilizando Razor Pages";
        }
    }
}

O resultado da execução desta Razor Page pode ser observado na próxima imagem:

A estrutura de um projeto baseado no template Web Application está detalhada na imagem a seguir:

  • A pasta Pages conterá as Views Razor do projeto (com seus arquivos .cshtml e .cshtml.cs);
  • Percebe-se ainda a inexistência de pastas para Controllers e suas respectivas Views, já que Razor Pages acabam por funcionar como Actions (ainda assim desvinculadas de um Controller).

Para maiores informações sobre as Razor Pages, consulte este link da documentação oficial do ASP.NET Core.

O metapackage Microsoft.AspNetCore.All

Ao se criar um novo projeto baseado no ASP.NET Core 2.0, o arquivo .csprojcorrespondente contará com uma única referência, apontando para Microsoft.AspNetCore.All:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
  </ItemGroup>

  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
  </ItemGroup>

</Project>

O metapackage Microsoft.AspNetCore.All engloba todos os packages que fazem parte do ASP.NET Core 2.0. Isto pode suscitar, num primeiro momento, a impressão de que referências desnecessárias integrarão projetos nesta nova versão.

Na prática, ao se instalar o .NET Core 2.0, todos os pacotes que compõem o ASP.NET Core 2.0 serão disponibilizados em uma área chamada Runtime Store. Embora ainda seja possível referenciar packages da maneira antiga (como acontecia até a versão 1.1), esta nova abordagem traz benefícios reais.

A primeira vantagem está relacionada a uma maior performance ao carregar inicialmente uma aplicação para execução.

Outro ponto em que o uso do metapackage Microsoft.AspNetCore.All oferece melhorias diz respeito ao gerenciamento das dependências de uma aplicação. Inúmeros pacotes, cada um com seu respectivo número de versão, podem acarretar dúvidas sobre qual release instalar ou, até mesmo, ocasionar erros decorrentes de uma escolha incorreta. Um único número de versão para o metapackage contribui para simplificar significativamente todo este processo.

Mudanças na criação de projetos via linha de comando

Diferentemente de versões anteriores, ao se executar o comando .NET new para criação de um novo projeto, também ocorrerá o restore das dependências do mesmo. Esta nova característica dispensa, num primeiro momento, o uso imediato da instrução .NET restore.

Como exemplo disto, temos a linha de comando dotnet new mvc -n ExemploMVC, executada a partir do Terminal no Ubuntu 17.04:

Configurações de web host

Até a versão 1.1 do ASP.NET Core, as configurações de web host eram geradas automaticamente no método Main da classe Program, acionando operações como UseKestrel, UseContentRoot e UseIISIntegration:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;

namespace ExemploSite
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .UseApplicationInsights()
                .Build();

            host.Run();
        }
    }
}

Embora ainda disponíveis, ao se criar um novo projeto baseado na versão 2.0, estas funções serão substituídas pelo método CreateDefaultBuilder da classe WebHost (namespace Microsoft.AspNetCore).

A chamada ao método CreateDefaultBuilder acontecerá a partir da função BuildWebHost. Esta operação será, então, invocada via método Main:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace ExemploSite
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}

Mudanças na classe Startup

As configurações definindo o uso do arquivo appSettings.json (e outros recursos contendo informações deste gênero) eram ativadas até o ASP.NET Core 1.1 no construtor da classe Startup, através de uma instância do tipo ConfigurationBuilder. Ao se criar um novo projeto o método Configure, também continha instruções especificando o uso de um mecanismo de log via interface ILoggerFactory (namespace Microsoft.Extensions.Logging):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace ExemploSite
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile(quot;appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

Ao se criar um novo projeto baseado no ASP.NET Core 2.0, será possível notar que uma referência baseada na interface IConfiguration (namespace Microsoft.Extensions.Configuration) foi repassada ao construtor da classe Startup. Além disso, percebe-se a ausência de uma instância de ILoggerFactory na declaração do método Configure:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace ExemploSite
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
        }
    }
}

E para finalizar, gostariam de saber um pouco mais sobre as novidades do .NET Core 2.0, ASP.NET Core 2.0, do .NET Standard 2.0 e do Update 15.3 do Visual Studio 2017? Não deixem de assistir, então, a gravação de um hangout realizado recentemente pelo canal Coding Night sobre este assunto: