ASP.NET 5

Introdução

Passados mais epende 13 anos sobre o lançamento do ASP.NET, a Microsoft decidiu começar do zero… ou quase. Com efeito, com o ASP.NET 5 vamos assistir a uma revolução no desenvolvimento para a web, que irá levar a uma reaprendizagem de todo o processo de desenvolvimento.

Um Bocado de História

ASP.NET: evoluçãoQuando o ASP.NET foi lançado, em 2002, a designação Web Forms era quase um pleonasmo: basicamente, não havia outro modelo de desenvolvimento para a web na framework .NET. A ideia da Microsoft era reproduzir, tanto quanto possível, em ambiente web o modelo de desenvolvimento já existente para o Windows:

  • Designer visual de páginas e controlos (drag and drop);
  • Modelo de eventos;
  • Manutenção automática de estado.

Em grande parte, estes objectivos foram bem-sucedidos: era possível a uma pessoa com relativamente poucos conhecimentos de desenvolvimento produzir aplicações ricas com controlos visuais e acesso a dados de forma rápida. Muitos fabricantes de software começaram a produzir bibliotecas de controlos e frameworks de desenvolvimento sobre Web Forms, permitindo a construção facilitada de ricas interfaces gráficas com funcionalidades avançadas, quase ao nível do que é possível encontrar em aplicações Windows Forms e Windows Presentation Foundation (WPF). A boa integração dos vários produtos da Microsoft com o Visual Studio deixou muita gente satisfeita durante bastante tempo. O SharePoint, o servidor colaborativo “de bandeira” da Microsoft, usa Web Forms, pelo que quem desenvolve para SharePoint tem obrigatoriamente de conhecer a framework.

Algumas versões notáveis do ASP.NET:

  • 1.0: versão inicial (Visual Studio .NET, Visual Studio 2003);
  • 2: introdução do mecanismo de providers (fornecedores de funcionalidades); disponibilização das ASP.NET AJAX Extensions; adaptadores de CSS configuráveis (Visual Studio 2005);
  • 3.5: integração das ASP.NET AJAX Extensions; novos controlos ListView e DataPager; LinqDataSource e EntityDataSource; routing; disponibilização do modelo MVC (Visual Studio 2008);
  • 4.0: páginas assíncronas; integração dos controlos gráficos ASP.NET Chart Controls; transformações do Web.config; mais fornecedores de funcionalidades (codificação de respostas, cache); novo modelo de validação de pedidos; inclusão do jQuery e do Modernizr; suporte a Content Delivery Networks (CDNs); view state opcional por página e controlo; geração de identificadores no lado do cliente configurável; possibilidade de endereçar diferentes versões do .NET; geração de HTML optimizado; disponibilização do ASP.NET Dynamic Data (Visual Studio 2010);
  • 4.5: binding model para controlos de exibição e inserção de dados; empacotamento (bundling) e minificação integrada; optimizações na garbage collection; suporte a mais funcionalidades do HTML 5; suporte a WebSockets; integração da biblioteca Microsoft AntiXSS; integração do WebAPI; integração do SignalR; integração de formas de autenticação sociais, como Facebook, Twitter, etc (Visual Studio 2012, Visual Studio 2013).

Entretanto, sobre Web Forms foram sido construídas outras frameworks: XML Web Services e Web Services Enhancements (para a versão 1.0), ASP.NET AJAX Extensions (2), ASP.NET Provider Model (2), Dynamic Data (3.5), Routing (3.5), SignalR (4.5), para citar apenas algumas, e a própria base foi evoluindo, tornando-se mais extensível e completa, com um mecanismo que permite trocar grande parte das funcionalidades nativas. A versão mais recente é a 4.5.2.

Críticas ao Modelo Web Forms

Grande parte das críticas ao modelo Web Forms assenta essencialmente nos seguintes aspectos:

  • A web é complexa e o modelo Web Forms esconde essa complexidade (manutenção de estado, actualizações parciais, etc);
  • A utilização do designer visual para produzir funcionalidades conceptualmente complexas pode levar a uma má separação de código, onde a própria página chega a conter código SQL ou LINQ;
  • A existência do view state e a dependência que certos controlos têm dessa funcionalidade, que por vezes faz com que as páginas fiquem extremamente “pesadas”, contendo grandes quantidades de dados que, de forma invisível, atrasam a sua submissão;
  • A dependência de uma biblioteca JavaScript embutida para algumas das suas funcionalidades (ASP.NET AJAX Library);
  • A complexidade/pouca qualidade do código gerado automaticamente pelos seus controlos: até há bem pouco tempo estes geravam elementos TABLE e outro conteúdo HTML que actualmente é considerado má prática;
  • O modelo “same-page” por omissão leva a que uma só página contenha muita lógica, porque a página faz submissões para si própria e tem de considerar várias acções possíveis aquando do processamento dos eventos;
  • O ciclo de vida de uma página e dos seus controlos é complexo; há certas coisas que têm de ser feitas em (ou até) determinado evento e por vezes é difícil sincronizar as dependências entre os vários controlos e a própria página (“event hell”);
  • Monolítico e pesado; as novas versões apenas são distribuídas com a própria framework .NET, o que não acontece tão frequentemente como isso; além disso, para usar uma qualquer funcionalidade, temos de trazer várias dependências atrás;
  • Apesar da adição tardia de routing, as páginas Web Forms não são geralmente amigas de Search Engine Optimization (SEO), dependendo de URLs relativamente crípticos (ex: /Categorias.aspx?ID=b1aee664-aa95-44bb-a0c8-45a567b56919, por oposição a /Categoria/Smartphone).

ASP.NET MVC

ASP.NET MVC: versõesO modelo de desenvolvimento MVC foi lançado em 2009 com o objectivo de fornecer uma alternativa “oficial” a quem não gostasse do Web Forms. Como grandes vantagens, propunha:

  • A familiaridade de um design pattern, Model-View-Controller (MVC), usado noutras linguagens e frameworks de desenvolvimento para a web (Java, PHP);
  • Uma distinção clara entre as várias camadas de desenvolvimento, conducente a uma melhor separação de responsabilidades, que eventualmente poderá levar a código mais fácil de manter e evoluir;
  • O regresso ao HTTP e HTML: o programador passa a ter de considerar questões como os verbos HTTP, os URLs e a gerar ele próprio o HTML dos conteúdos, o que lhe dá mais controlo; a necessidade de produzir HTML levou a uma maior utilização de frameworks JavaScript;
  • O modelo de rotas leva a URLs mais “amigos” de REST e de SEO, tópicos “quentes” actualmente;
  • Mais facilidade em testar o código por meio de testes unitários;
  • A disponibilização de actualizações “out-of-band”, ou seja, não coincidentes com as actualizações da framework .NET, levando a que possam ser mais frequentes;
  • Elevada extensibilidade: abraçando conceitos modernos, tais como Dependency Injection (DI) e Inversion of Control (IoC), é possível substituir ou complementar grande parte dos seus mecanismos internos (validação, autenticação, autorização, logging, etc). Praticamente todas as funcionalidades são extensíveis.

O modelo MVC tornou-se muito popular. Apesar de ainda não poder rivalizar com o Web Forms nalguns aspectos – falta de designer visual, menor capacidade de reutilização de controlos – rapidamente se tornou a framework de escolha para muitos programadores com tecnologias Microsoft, descontentes com o modelo anterior. A própria Microsoft pareceu empurrar nessa direcção, incluindo até o apoio a projectos construídos sobre MVC, externos (Orchard, por exemplo) ou internos (Web API, Web Pages, Razor) e à especificação OWIN. Como prova dessa evolução, podemos ver que passou da versão 1, em 2009, para a versão 5 em 2013, com vários lançamentos pelo meio, estando actualmente na 5.2.3.

OWIN e Open Source

Numa tentativa de “democratizar” o ASP.NET, levando-o a outros sistemas operativos, juntamente com o resto da família .NET, a Microsoft libertou grande parte do código fonte como open source, sob o licenciamento Microsoft Public License (MS-PL). Adicionalmente, tem vindo a trabalhar numa especificação que define o fluxo de processamento de um pedido pelo servidor e como o código .NET se pode integrar com um servidor HTTP que não exclusivamente o IIS: é o standard Open Web Integration for .NET (OWIN). O problema é que OWIN, neste momento, não se integra verdadeiramente com Web Forms, embora seja possível usá-los em conjunto, de forma a suportar componentes que dependam de OWIN num cenário Web Forms, mas a framework Web Forms propriamente dita não o usa, ao contrário da MVC. Todo o desenvolvimento continua a assentar na velha pipeline ASP.NET e nas bibliotecas System.Web.DLL e System.Web.Extensions.DLL.

ASP.NET vNext

Na realidade o que temos em cima da mesa é não uma mas duas versões do ASP.NET:

  • 4.6: trata-se da evolução natural da versão actual do ASP.NET; inclui alguns melhoramentos em Web Forms e MVC e integra várias correcções de segurança entretanto lançadas;
  • 5: reescrita total do ASP.NET.

ASP.NET: Open .NET 2015Foquemo-nos no ASP.NET 5. Esta nova framework – pois é disto que estamos a falar – vai funcionar sobre o .NET 5. As suas principais características vão ser:

  • Totalmente open source sob a licença MIT; serão aceites contributos da comunidade, como já agora acontece;
  • Fim do modelo de desenvolvimento Web Forms; não será incluído com o ASP.NET 5 qualquer classe de suporte ao Web Forms;
  • C# e VB serão suportados, apesar de inicialmente a Microsoft ter anunciado que não existiria suporte inicial para VB;
  • Baseado em OWIN, sendo que a framework “natural” de desenvolvimento será MVC e Razor, mas será alojável em vários servidores, desde o IIS até o novo Kestrel, desenvolvido de raiz para Mac e Linux, passando por correr num processo .NET;
  • Por assentar em .NET 5, será implicitamente multi-plataforma, devendo correr em Windows, Mac e Linux, com suporte a versões limitadas do .NET (.NET Core CLR) a pensar na cloud, e podendo usar simultaneamente componentes de várias versões do .NET;
  • Será modular e suportado em packages NuGet: as novas versões serão distribuídas “out-of-band” sob a forma de packages NuGet; os programadores poderão escolher apenas aquelas de que necessitam; estas serão actualizadas em ciclos próprios, não ditados pelas novas versões da framework .NET;
  • Unificação dos APIs MVC, Web API e Web Pages, para evitar duplicação e fornecer um modelo coerente e coeso, sobre a pipeline especificada pelo OWIN;
  • Totalmente extensível por meio de DI e IoC, sendo fornecido um contentor próprio, que pode ser substituído por um mais tradicional (AutoFac, Unity, Ninject, etc);
  • Compilação dinâmica: deixa de ser necessário compilar o código explicitamente para experimentar as alterações, estas são detectadas automaticamente e compiladas pelo novo compilador Roslyn;
  • Novas ferramentas de linha de comandos com nomes estranhos: DNX, DNVM e DNU;
  • Integração com bibliotecas populares de desenvolvimento e gestão de dependências JavaScript, como Bower, Grunt, Gulp e NPM;
  • Gestão de dependências de bibliotecas .NET por meio de packages NuGet e suas versões em ficheiros JSON;
  • Suporte ao HTTP 2.0, quando a correr sobre o Windows 10 ou superior.

Reconhecendo os problemas actuais – código monolítico, muito agarrado e com muitas dependências, obrigatoriedade de respeitar os ciclos mais lentos de lançamento da framework .NET, grande disparidade e duplicação de funcionalidades entre o MVC, Web API e Web Pages, a Microsoft decidiu começar de raiz e reescrever a framework a partir do zero. O novo ambiente de desenvolvimento integrado (IDE) será o Visual Studio 2015 e irá suportar quer a nova framework baseada em .NET 5 quer as anteriores.

Exemplos

Ao criar um novo projecto web com o Visual Studio 2015 RC somos confrontados com as seguintes opções:

ASP.NET: novo projecto

Um projecto ASP.NET 5 consiste numa pasta com um ficheiro project.json:

ASP.NET: estrutura de projecto

Dentro deste, temos algo como:

{
  "webroot": "wwwroot",
  "userSecretsId": "aspnet5-WebApplication1-108e0908-d4ac-4341-920e-ce646e4c2b33",
  "version": "1.0.0-*",
  "dependencies": {
    "Microsoft.AspNet.Mvc": "6.0.0-beta4",
    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-beta4",
    "Microsoft.AspNet.Diagnostics": "1.0.0-beta4",
    "Microsoft.AspNet.Diagnostics.Entity": "7.0.0-beta4",
    "Microsoft.AspNet.Server.IIS": "1.0.0-beta4",
    "Microsoft.AspNet.Server.WebListener": "1.0.0-beta4",
    "Microsoft.AspNet.StaticFiles": "1.0.0-beta4",
    "Microsoft.AspNet.Tooling.Razor": "1.0.0-beta4",
    "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta4",
    "Microsoft.Framework.ConfigurationModel.UserSecrets": "1.0.0-beta4",
    "Microsoft.Framework.CodeGenerators.Mvc": "1.0.0-beta4",
    "Microsoft.Framework.Logging": "1.0.0-beta4",
    "Microsoft.Framework.Logging.Console": "1.0.0-beta4",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-beta4"
  },
  "commands": {
    "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000",
    "gen": "Microsoft.Framework.CodeGeneration",
  },
  "frameworks": {
    "dnx451": { },
    "dnxcore50": { }
  },
  "exclude": [ "wwwroot", "node_modules", "bower_components" ],
  "publishExclude": [ "node_modules", "bower_components", "**.xproj", "**.user", "**.vspscc" ],
  "scripts": {
    "postrestore": [ "npm install", "bower install" ],
    "prepare": [ "gulp copy" ]
  }
}

São perceptíveis os seguintes elementos:

  • Informação genérica do projecto: webroot, userSecretsId, version; userSecretsId contém um identificador único da aplicação usado para localizar um ficheiro de configuração pessoal por utilizador;
  • Dependências NuGet: dependencies;
  • Comandos: commands; neste exemplo, o comando web despoleta o servidor HTTP WebListener;
  • Frameworks suportadas: frameworks;
  • Pastas e ficheiros excluídos do projecto (por omissão, todos os ficheiros dentro de uma pasta estão incluídos): exclude;
  • Pastas e ficheiros excluídos da publicação: publishExclude;
  • Scripts executáveis: scripts. São visíveis elementos do Bower, NPM e Gulp.

Não iremos percorrer todos estes elementos, a maior parte deles é facilmente compreensível. É interessante ver que o ficheiro possui IntelliSense:

ASP.NET: IntelliSense nas packages NuGetASP.NET: IntelliSense no ficheiro project.jsonAo adicionar uma dependência, o Visual Studio detecta a alteração e faz o seu download:ASP.NET: download automático de dependências

Não existem mais os ficheiros Web.config e Global.asax/Global.asax.cs: a configuração é agora extensível sendo por omissão suportados ficheiros JSON e as variáveis de ambiente, e a pipeline do projecto é inteiramente OWIN. A classe que por convenção permite configurar a aplicação chama-se Startup:

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        // Definir a fonte da configuração a partir de um ficheiro e das variáveis de ambiente
        var configuration = new Configuration()
            .AddJsonFile("config.json")
            .AddUserSecrets()
            .AddEnvironmentVariables();
 
        // Guardar a configuração numa propriedade local 
        this.Configuration = configuration;
    }

    public IConfiguration Configuration { get; set; } 

    public void ConfigureServices(IServiceCollection services)
    {
        // Adicionar um serviço com scope do pedido HTTP actual
        services.AddScoped<IService, ServiceImplementation>());
        // Adicionar um serviço a ser criado em cada pedido por ele
        services.AddTransient<IService, ServiceImplementation>();
        // Adicionar um serviço singleton
        services.AddSingleton<IService>(new ServiceImplementation());
 
        // Adicionar MVC ao contentor de IoC e DI
        services.AddMvc();
        // Descomentar para adicionar Web API
        // services.AddWebApiConventions();
    }
 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
    {
        // Configurar o logging
        loggerfactory.AddConsole(minLevel: LogLevel.Warning);
 
        // Se estivermos em ambiente de desenvolvimento, mostrar erros
        if (env.IsEnvironment("Development"))
        {
            app.UseBrowserLink();
            app.UseErrorPage(ErrorPageOptions.ShowAll);
            app.UseDatabaseErrorPage(DatabaseErrorPageOptions.ShowAll);
        }
        else
        {
            // Caso contrário, redireccionar para este controlador e acção no caso de erros
            app.UseErrorHandler("/Home/Error");
        }

        // Servir ficheiros estáticos
        app.UseStaticFiles();

        // Configurar rotas MVC
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller}/{action}/{id?}",
                defaults: new { controller = "Home", action = "Index" });
 
            // Descomentar para configurar rotas Web API
            // routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}");
        });
    }
}

Os três métodos chamados por convenção são:

  • Startup: permite definir opções de alojamento do serviço HTTP e definições globais;
  • ConfigureServices: adicionar ou substituir serviços no contentor de IoC e DI, com uma de três longevidades possíveis:
    • Singleton: apenas existe uma instância, esta é sempre devolvida;
    • Scoped: é criada uma instância, caso não exista, por pedido HTTP, após o que, dentro do mesmo pedido, é sempre devolvida a instância criada;
    • Transient (default): é criada uma nova instância do serviço sempre que for pedida ao contentor de IoC.
  • Configure: outros aspectos da configuração, já usando os serviços definidos (rotas, logging, etc), adicionar middleware à pipeline
    Nota: alguns nomes da especificação OWIN foram alterados no ASP.NET 5; o interface IAppBuilder passou para IApplicationBuilder, por exemplo.

O registo de middleware – adicionar funcionalidades à pipeline HTTP – é tipicamente feito no método Configure:

// Adicionar um componente à pipeline de execução
app.UseMiddleware<MeasureMiddleware>();

Um exemplo de um componente OWIN, que vem substituir os módulos e handlers HTTP (IHttpModule e IHttpHandler) será:

public class MeasureMiddleware
{
    private readonly RequestDelegate _next;
 
    public MeasureMiddleware(RequestDelegate next)
    {
        this._next = next;
    }
 
    public async Task Invoke(HttpContext context)
    {
        var sw = Stopwatch.StartNew();
 
        await this._next(context);
 
        var ext = Path.GetExtension(context.Request.Path.Value);
 
        if ((context.Response.StatusCode == (Int32) HttpStatusCode.OK) && (String.IsNullOrWhiteSpace(ext) == true))
        {
            var milliseconds = sw.ElapsedMilliseconds;
 
            await context.Response.WriteAsync($"Processado em {milliseconds} milisegundos");
        }
    }
}

Este componente faz uso do padrão Chain of Responsibility para invocar o componente anterior (middleware) na pipeline (recebido no construtor), medindo essa execução e fazendo output do tempo que demorou. Tem acesso ao contexto de execução, incluindo todos os detalhes do pedido, e pode adicionar conteúdo às respostas.

ASP.NET: middleware

A configuração global num ficheiro JSON (config.json) fica assim:

{
  "AppSettings": {
    "SiteTitle": "WebApplication1"
  },
  "Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=aspnet5-WebApplication1-108e0908-d4ac-4341-920e-ce646e4c2b33;Integrated Security=SSPI;MultipleActiveResultSets=true"
    }
  }
}

No nosso exemplo, estamos a combinar configuração específica do projecto (AddJsonFile) com variáveis de ambiente do utilizador (AddEnvironmentVariables) e também com um ficheiro de configuração pessoal do utilizador, o qual não é mantido na mesma pasta do projecto, mas numa pasta específica do utilizador (%AppData%\Roaming\Microsoft\UserSecrets\<nome da aplicação>\secrets.json, por omissão).

Outra diferença importante é que a raiz do servidor HTTP, a partir da qual são servidos os ficheiros estáticos, está situada numa pasta chamada, por omissão, wwwroot (configurada no project.json), e não na pasta do projecto propriamente dito:

ASP.NET: wwwroot

Também o Bower e o NPM merecem um tratamento especial, exibindo o Visual Studio uma vista sobre o conteúdo dos ficheiros de configuração bower.json, package.json e gulpfile.js:

ASP.NET: dependências

As dependências também provêm directamente do ficheiro project.json, da sua entrada frameworks:

ASP.NET: references

Já os controladores e as vistas, bem como as respectivas rotas, localizações e convenções de acesso, permanecem idênticas aos das versões anteriores do MVC, pelo que não serão cobertos aqui. Destaco apenas três novidades: apenas são suportadas vistas Razor e os controladores são partilhados por MVC e Web API, devendo retornar implementações de IActionResult, interface que é comum aos resultados de controladores MVC e Web API. A terceira são na verdade duas formas server-side de gerar conteúdos HTML. A primeira chama-se tag helpers, e é uma forma de definir tags cujos atributos e conteúdo, pelo menos parcialmente, são gerados por código .NET. Estes tag helpers são definidos em classes .NET que herdam de TagHelper:

[TargetElement("square")]
public class SquareTagHelper : TagHelper
{
    [HtmlAttributeName("asp-side")]
    public Int32 ? Side { get; set; }
 
    [HtmlAttributeName("asp-background-color")]
    public String BackgroundColor { get; set; }
 
    [HtmlAttributeName("asp-foreground-color")]
    public String ForegroundColor { get; set; }

    [HtmlAttributeName("asp-content")]
    public String Content { get; set; }
 
    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        if ((this.Side != null) && (this.BackgroundColor != null))
        {
            //define a tag de output
            output.TagName = "div";
 
            //adiciona atributos à tag
            output.Attributes["style"] = $"width: {Side}px; height: {Side}px; color: {ForegroundColor}; background-color: {BackgroundColor}; text-align: center; vertical-align: middle; line-height: {Side}px;";
 
            //adiciona conteúdo
            output.Content.SetContent(this.Content);
        }
 
        base.Process(context, output);
    }
}

E registados em vistas Razor, por exemplo, _GlobalImport.cshtml, por forma a estarem acessíveis em todas as vistas:

@using MyNamespace
@using MyNamespace.Models
@addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers"
@addTagHelper "*, MyNamespace"

A instrução addTagHelper torna disponível todas as tag helpers disponíveis numa assembly .NET. Após este registo, podemos usar a nova tag square:

<square asp-side="200" asp-foreground-color="white" asp-background-color="blue" asp-content="Hello, World!"/>

Alguns leitores poderão notar semelhanças com o modelo de controlos server-side do ASP.NET Web Forms.

O segundo novo API chama-se view components. Aqui a ideia é ter um mecanismo semelhante às partial views, simplesmente, sem designer, ou seja, todo o conteúdo é produzido por código. Vejamos um exemplo de um view component, uma classe que herda de ViewComponent:

[ViewComponent(Name = "Sum")]
public class AddViewComponent : ViewComponent
{
    public IViewComponentResult Invoke(int a, int b)
    {
        var result = a + b;
        return this.View(result);
    }
}

E eis como o utilizar numa vista Razor:

@Component.Invoke("Sum", 1, 2)

O primeiro parâmetro de Invoke é o nome do view component, tal como definido pelo atributo ViewComponentAttribute, caso exista, ou então o nome da classe sem o sufixo ViewComponent. Seguidamente vão quaisquer parâmetros, que irão ser passados ao método Invoke. Poderão existir vários overloads deste método, recebendo diferentes parâmetros e é também possível invocar o view component assincronamente.

Com estes dois mecanismos, tag helpers e view components, torna-se mais fácil a invocação de código server-side, e o que não é de somenos importância, a reutilização, já que estes componentes podem existir em assemblies externas para as quais foram adicionadas referências.

Novos Ferramentas da Linha de Comandos

À boleia do .NET 5 vem um conjunto de comandos novo; entre outras novidades, passa a ser possível gerir packages NuGet e correr aplicações ASP.NET sem usar o Visual Studio. Os três novos comandos com os quais teremos de nos familiarizar são, muito resumidamente:

  • DNVM: .NET Version Manager, anteriormente chamado KVM; configura a versão do .NET do projecto;
  • DNX: .NET Execution Environment, anteriormente K, KLR e KRE; permite configurar o ambiente do .NET em uso pelo projecto, de entre .NET Framework (default), .NET Core (subset optimizado para cloud) e Mono (para Linux e Mac);
  • DNU: .NET Development Utilities, antigo KPM; utilitários para gerir as packages NuGet, criar packages e publicar a aplicação.

Estes comandos integram-se com a nova estrutura de projectos .NET (project.json). Alguns exemplos:

ASP.NET: Lista de frameworks instaladasASP.NET: Instalar a última versão das frameworks ASP.NET: Seleccionar a framework a usarASP.NET: Definir um alias para uma frameworkASP.NET: Executar um comando definido no projecto

Para o DNU, os comandos mais típicos serão:

  • dnu restore: obter todas as packages NuGet especificadas no projecto que estejam em falta;
  • dnu publish: preparar a aplicação para deployment;
  • dnu wrap: converter um projecto .csproj em json;
  • dnu build: compilar o projecto.

Os comandos DNX, DNVM e DNU actuam com base e sobre o projecto actual, que pode ser ASP.NET 5 ou outro .NET 5.

Conclusão

Como o ASP.NET 5, bem como o 4.6, ainda não foram lançados, só nos resta especular. É possível que alguém, ou mesmo a própria Microsoft, venha a implementar Web Forms sobre o ASP.NET 5. Certo parece ser um cada vez maior impulso na direcção do Azure, multi-plataforma e também do open source. Durante algum tempo ainda teremos a família 4.x, com suporte a código legado, mas é de prever que esta seja descontinuada num futuro próximo. Esperemos pela versão final do Visual Studio 2015 e ASP.NET 5, que deverá ser lançada ainda este ano, e, entretanto, estejamos atentos às novidades que vão sendo apresentadas.

Referências