[ASP.NET] ASP.NET 5 – vNext

ASP.NET logoASP.NET vNext a été annoncé il y a quelques mois maintenant. Depuis, le futur de la plate-forme web de Microsoft se dessine de plus en plus concrètement. Je vous propose, au travers de ce billet et des prochains, d’analyser l’impact des évolutions apportées au Framework et d’apprendre à les utiliser.

K ?

Si vous vous intéressez à ASP.NET 5 (ASP.NET vNext), vous ne manquerez pas de tomber sur une suite d’outils et de termes préfixés de la lettre K. Il s’agit en fait des différents éléments qui composent la plate-forme ASP.NET 5. Cette nouvelle version est l’occasion pour Microsoft de faire table rase des lourdeurs de son passé dans le développement d’applications Web en étendant au mieux tous les avantages des concepts apportés par ses différents frameworks les plus récents (ASP.NET MVC, ASP.NET Web API, Signal R ou encore Katana).

Si vous ne l’avez pas encore fait, je vous invite à consulter mes précédents billets sur OWIN et sur Katana. Ils vous permettront d’appréhender au mieux certains concepts liés à ASP.NET 5. L’objectif principal était de dé corréler l’applicatif du type de serveur utilisé, et donc de casser le couplage fort qu’il pouvait exister entre une application ASP.NET et IIS.

Pour faire simple, ASP.NET 5 est une profonde refonte qui pousse les concepts apportés par OWIN encore plus loin. En effet, la première avancée à signaler est le possibilité de découpler son applicatif de l’assembly System.Web. Cela permet notamment d’avoir un nouveau pipeline HTTP plus léger et plus performant, à noter également que les ressources mémoires allouées à chaque requête entrante sur le serveur sont donc diminuées, puisqu’elles sont allégées de tout l’historique d’ASP.NET (et de WebForms).

Ensuite, le mode de distribution du Framework .NET pour les applications Web a été revu. Jusqu’à présent, une application ASP.NET reposait sur une version majeure du Framework .NET. A partir du moment où cette version était installée sur un serveur, elle allait permettre l’exécution d’une application Web, mais aussi d’une application WinForms ou WPF. L’inconvénient étant que la distribution de nouvelles versions, qu’il s’agisse de mise à jour de sécurité critique ou d’ajouts de nouvelles fonctionnalités, est assez complexe et lourde à réaliser.

ASP.NET 5 est donc centré autour d’un premier élément : le KRE (K Runtime Environnement). En quelques mots, il s’agit d’un moteur permettant de sélectionner et modifier facilement l’environnement d’exécution utilisé par une application. L’autre nouveauté concerne ces environnements d’exécution. Pour le moment, trois sont d’ores et déjà utilisables :

  • La CLR .NET historique ; c’est l’environnement par défaut, qui contient toutes les APIs .NET et qu’il faut privilégier essentiellement dans les projets où la rétro compatibilité (avec WebForms par exemple) est cruciale.

  • Le Core CLR (aussi appelé Cloud Optimized) est une version allégée de la CLR .NET classique. Elle est beaucoup plus légère que la CLR classique, environ 20 fois plus petite, et ne contient que les éléments strictement nécessaires à l’exécution d’une application Web. Exit donc les APIs utilisée par WPF ou Winforms par exemple.

  • La CLR Mono, c’est une autre des grandes nouveautés, puisque Microsoft a annoncé dans un premier temps supporter totalement cette CLR et l’intégrer dans son cycle de tests afin d’assurer sa compatibilité avec ses différents Frameworks Web. Dans un second temps et avec des annonces plus récentes, Microsoft a même annoncé une nouvelle CLR Cross Platform qui serait développée conjointement avec les équipes de Mono. A noter également avec ce dernier point, qu’il devient facile de développer et d’héberger une application ASP.NET sur Linux. Souvenez-vous des efforts fait avec OWIN pour découpler l’applicatif du serveur, et bien, nous retrouvons totalement ces concepts avec ASP.NET. Cela ne prend donc que quelques secondes pour démarrer une application MVC 6 sous Linux en utilisant le serveur de son choix. Notez également que l’intégralité d’ASP.NET 5 et des différents éléments qui gravitent autour est open source et disponible sur GitHub. Vous pouvez en suivre le développement au jour le jour et même y contribuer.

L’outil qui doit permettre l’installation et l’utilisation de versions différentes de la CLR en parallèle s’appelle KVM : K Version Manager. Cela résout les problématiques de cohabitation d’une application ancienne, dépendant d’une version spécifique de la CLR avec une application souhaitant utiliser les fonctionnalités les plus récentes. Ces différents versions de CLR sont accessibles facilement sous la forme de paquet Nuget.

Il y a également des nouveautés dans la gestion des dépendances d’une application. La nouvelle brique concernée s’appelle KPM : K Package Manager. Là encore, les dépendances d’une application ASP.NET 5 seront entièrement gérées sous la forme de paquets Nuget. Le développeur exprime ces dépendances au travers d’un fichier JSON (en quelque sorte, une refonte des csprojet actuels) et fait appel à KPM pour résoudre ces dépendances.

Enfin, cette release s’accompagne de biens d’autres nouveautés sur lesquelles j’aurais l’occasion de revenir dans d’autres billets : MVC 6 et le merge avec Web API, l’injection de dépendance en natif, le déploiement vers Azure simplifié, etc.

Pour l’heure, dans ce billet, je vous propose un premier contact avec ASP.NET 5 en installant un environnement de développement sans Visual Studio et en apprenant à utiliser les différents outils K**.

Préparation de l’environnement

Pour commencer avec ASP.NET vNext, nous allons utiliser les outils en ligne de commande plutôt que Visual Studio. Je vous invite à cloner le repository Git du KVM avec la commande git clone https://github.com/aspnet/kvm.git.

Une fois les sources téléchargées, vous trouverez à la racine du répertoire un fichier build.cmd. Exécutez-le. Vous obtiendrez une série de fichiers dans un sous répertoire artifacts. Prenez ces fichiers et copiez les dans l’arborescence C:\Users\leo.kre\bin (leo étant mon nom d’utilisateur Windows). Dernière étape, modifiez votre variable d’environnement PATH et ajoutez-y le répertoire précédent (C:\Users\leo.kre\bin).

Votre environnement est presque prêt ! Ouvrez une invite de commande et tapez kvm. Une liste de commandes et d’options utilisables devraient alors apparaître à l’écran. C’est donc la commande kvm qui va vous permettre de gérer les différentes versions de runtime installées sur votre poste. Commencez par récupérer les versions les plus récentes du runtime grâce à la commande kvm upgrade.

Dans mon cas, la sortie suivante est affichée. Cela peut bien évidemment varier selon les versions du runtime qui seront sorties entre le jour où j’écris ces lignes et le jour où vous les lirez.

PS C:\Users\leo> kvm upgrade
Determining latest version
Downloading KRE-CLR-x86.1.0.0-beta2-10688 from https://www.myget.org/F/aspnetvnext/api/v2
Unpacking to C:\Users\leo\.kre\packages\temp
Installing to C:\Users\leo\.kre\packages\KRE-CLR-x86.1.0.0-beta2-10688
Adding C:\Users\leo\.kre\packages\KRE-CLR-x86.1.0.0-beta2-10688\bin to process PATH
Adding C:\Users\leo\.kre\packages\KRE-CLR-x86.1.0.0-beta2-10688\bin to user PATH
Updating alias 'default' to 'KRE-CLR-x86.1.0.0-beta2-10688'

On peut cependant en tirer plusieurs informations intéressantes :

  • Le feed de publication des versions de la KRE est un feed Nuget situé à l’adresse https://www.myget.org/F/aspnetvnext/api/v2
  • Mêmes si les runtimes peuvent être installés en side by side, les différentes versions sont toutes téléchargées et installées dans un repository local centralisé (dans mon cas C:\Users\leo.kre\packages)
  • Les versions et type de runtime peuvent être aliasés. Dans mon cas, la version 1.0.0-beta2-10688 de la CLR complète a été associée à l’alias nommé default. Cela me permettra de pouvoir la sélectionner plus facilement.

Il existe d’autres commutateurs utilisables avec la commande kvm. Par exemple, l’instruction kvm list vous retourne toutes les versions du runtime présentes sur votre poste. Nous en découvrirons l’usage plus loin dans ce billet.

PS C:\Users\leo> kvm list

Active Version           Runtime Architecture Location                   Alias
------ -------           ------- ------------ --------                   -----
       1.0.0-beta1       CLR     amd64        C:\Users\leo\.kre\packages
       1.0.0-beta1       CLR     x86          C:\Users\leo\.kre\packages
       1.0.0-beta1       CoreCLR amd64        C:\Users\leo\.kre\packages
       1.0.0-beta1       CoreCLR x86          C:\Users\leo\.kre\packages
       1.0.0-beta2-10665 CLR     x86          C:\Users\leo\.kre\packages
       1.0.0-beta2-10677 CLR     x86          C:\Users\leo\.kre\packages
  *    1.0.0-beta2-10688 CLR     x86          C:\Users\leo\.kre\packages default

J’ai également la possibilité de télécharger et d’installer une version spécifique du runtime. Par exemple la commande kvm upgrade suivante me permet de récupérer la version la plus récente du runtime dans sa version Cloud Optimized (nommée par CoreCLR par KVM).

PS C:\Users\leo> kvm upgrade -r CoreCLR
Determining latest version
Downloading KRE-CoreCLR-x86.1.0.0-beta2-10688 from https://www.myget.org/F/aspnetvnext/api/v2
Unpacking to C:\Users\leo\.kre\packages\temp
Installing to C:\Users\leo\.kre\packages\KRE-CoreCLR-x86.1.0.0-beta2-10688
Adding C:\Users\leo\.kre\packages\KRE-CoreCLR-x86.1.0.0-beta2-10688\bin to process PATH
Adding C:\Users\leo\.kre\packages\KRE-CoreCLR-x86.1.0.0-beta2-10688\bin to user PATH
Updating alias 'default' to 'KRE-CoreCLR-x86.1.0.0-beta2-10688'
Compiling native images for KRE-CoreCLR-x86.1.0.0-beta2-10688 to improve startup performance...
Finished native image compilation.

Cette fois ci, un appel à kvm list me produit le résultat suivant.

PS C:\Users\leo> kvm list

Active Version           Runtime Architecture Location                   Alias
------ -------           ------- ------------ --------                   -----
       1.0.0-beta1       CLR     amd64        C:\Users\leo\.kre\packages
       1.0.0-beta1       CLR     x86          C:\Users\leo\.kre\packages
       1.0.0-beta1       CoreCLR amd64        C:\Users\leo\.kre\packages
       1.0.0-beta1       CoreCLR x86          C:\Users\leo\.kre\packages
       1.0.0-beta2-10665 CLR     x86          C:\Users\leo\.kre\packages
       1.0.0-beta2-10677 CLR     x86          C:\Users\leo\.kre\packages
       1.0.0-beta2-10688 CLR     x86          C:\Users\leo\.kre\packages
  *    1.0.0-beta2-10688 CoreCLR x86          C:\Users\leo\.kre\packages default

A présent, si vous ouvrez le dossier d’installation d’une version du runtime (par exemple C:\Users\leo.kre\packages\KRE-CLR-x86.1.0.0-beta2-10688\bin), peu importe laquelle, vous trouverez deux éléments intéressants :

  • Le fichier k.cmd, c’est lui qui sert de lanceur à nos application ASP.NET vNext ;
  • Le fichier kpm.cmd, c’est la commande qui nous permettra de restaurer les paquets (les dépendances) utilisées par notre application.

Nous avons maintenant assez de bagages pour démarrer une première application ASP.NET vNext.

Première approche d’ASP.NET vNext

Pour toute la suite de cette partie, nous continuerons à tout faire via la ligne de commande et un simple éditeur de texte (Notepad++ fait parfaitement l’afffaire).

Ouvrez un répertoire vide. Dans mon cas, dans le chemin D:\Projects\Demo. Créez-y un fichier nommé project.json. Ce nom est extrêmement important. C’est ici que vous allez définir les différentes dépendances utilisées par votre application, les points d’entrées de votre application ou encore le runtime à utiliser.

Ce fichier se construit sous la forme d’un objet JSON. L’exemple ci-dessous est un des plus simples possibles. Ici, seule une dépendance est déclarée : celle vers System.Console. Notez également qu’il est nécessaire de spécifier le numéro de version de la dépendance en question. Sachez que, via Visual Studio, l’ajout d’une dépendance et notamment la recherche d’une version spécifique est simplifiée, notamment grâce à de l’auto complétion dans l’édition d’un fichier project.json.

{
    "dependencies" : {
        "System.Console" : "1.0.0-beta2"
    }
}

Dans un second temps, nous allons créer une classe Program dans un fichier Program.cs.

namespace Demo
{
    public class Program
    {
        public static void Main()
        {
            System.Console.WriteLine("Console");
        }
    }
}

Dans le répertoire contenant votre fichier project.json, faîtes appel à KPM via la commande kpm restore. Cela indique à l’outil qu’il doit parser votre fichier project.json pour récupérer la liste des dépendances et qu’il doit les télécharger (ou les récupérer dans son cache local si possible).

PS D:\Projects\Demo> kpm restore
Restoring packages for D:\Projects\Demo\project.json
  GET https://www.nuget.org/api/v2/FindPackagesById()?Id='System.Console'.
  OK https://www.nuget.org/api/v2/FindPackagesById()?Id='System.Console' 640ms
  CACHE https://www.nuget.org/api/v2/FindPackagesById()?Id='System.IO'
  CACHE https://www.nuget.org/api/v2/FindPackagesById()?Id='System.Text.Encoding'
  CACHE https://www.nuget.org/api/v2/FindPackagesById()?Id='System.Threading.Tasks'
  CACHE https://www.nuget.org/api/v2/FindPackagesById()?Id='System.Runtime'
Resolving complete, 825ms elapsed
Restore complete, 849ms elapsed

Vous pouvez ensuite démarrez votre première application ASP.NET 5 via la commande k run. La sortie est la suivante.

PS D:\Projects\Demo2> k run
Console

Souvenez-vous, grâce à la commande kvm list, je peux obtenir les différentes versions de runtime présentes sur mon poste.

PS D:\Projects\Demo> kvm list

Active Version           Runtime Architecture Location                   Alias
------ -------           ------- ------------ --------                   -----
       1.0.0-beta1       CLR     amd64        C:\Users\leo\.kre\packages
       1.0.0-beta1       CLR     x86          C:\Users\leo\.kre\packages
       1.0.0-beta1       CoreCLR amd64        C:\Users\leo\.kre\packages
       1.0.0-beta1       CoreCLR x86          C:\Users\leo\.kre\packages
       1.0.0-beta2-10665 CLR     x86          C:\Users\leo\.kre\packages
  *    1.0.0-beta2-10677 CLR     x86          C:\Users\leo\.kre\packages default

Dans le résultat ci-dessus, on peut constater que le runtime actuellement actif (celui possédant une étoile dans sa colonne Active) est un runtime de type CLR. Cela signifie qu’il s’agit d’une version du Framework .NET classique. Celle qui nous permet d’accéder à toutes les APIs de .NET, y compris celles qui ne sont pas forcément utiles dans le cadre d’une application Web.

Modifiez à présent le code de votre application avec l’exemple ci-dessous. La classe AppDomain est une des APIs qui, à l’heure actuelle, n’est pas présente dans la version Core du Framework .NET. Elle doit cependant rester disponible dans la version complète du Framework.

namespace Demo
{
    public class Program
    {
        public static void Main()
        {
            System.Console.WriteLine(typeof(System.AppDomain).GetType().FullName);
        }
    }
}

Encore une fois, je peux exécuter mon application via une console grâce à la commande k run. Observez bien la sortie ci-dessous.

PS D:\Projects\Demo> k run
System.RuntimeType

Je vais maintenant remplacer le runtime actif en choisissant la version Cloud Optimized. C’est la commande kvm use qui me permet de choisir un runtime spéficique.

PS D:\Projects\Demo> kvm use 1.0.0-beta1 -r CoreCLR
Adding C:\Users\leo\.kre\packages\KRE-CoreCLR-x86.1.0.0-beta1\bin to process PATH

A nouveau, en listant les versions du runtime présentes sur mon poste, je peux à présent constater que la version active c’est plus la version classique du Framework .NET mais bien une version Cloud Optimized.

PS D:\Projects\Demo> kvm list

Active Version           Runtime Architecture Location                   Alias
------ -------           ------- ------------ --------                   -----
       1.0.0-beta1       CLR     amd64        C:\Users\leo\.kre\packages
       1.0.0-beta1       CLR     x86          C:\Users\leo\.kre\packages
       1.0.0-beta1       CoreCLR amd64        C:\Users\leo\.kre\packages
  *    1.0.0-beta1       CoreCLR x86          C:\Users\leo\.kre\packages
       1.0.0-beta2-10665 CLR     x86          C:\Users\leo\.kre\packages
       1.0.0-beta2-10677 CLR     x86          C:\Users\leo\.kre\packages default

En exécutant à nouveau l’application, la sortie est cette fois tout à fait différente. En effet, la classe AppDomain n’est pas présente dans le runtime Cloud Optimized, mon application ne peut donc plus fonctionner.

PS D:\Projects\Demo2> k run
System.InvalidOperationException: D:\Projects\Demo2\Startup.cs(7,43): error CS0234: The type or namespace name 'AppDomai
n' does not exist in the namespace 'System' (are you missing an assembly reference?)
   at Microsoft.Framework.ApplicationHost.Program.ThrowEntryPointNotfoundException(DefaultHost host, String applicationN
ame, Exception innerException)
   at Microsoft.Framework.ApplicationHost.Program.ExecuteMain(DefaultHost host, String applicationName, String[] args)
   at Microsoft.Framework.ApplicationHost.Program.Main(String[] args)

Mon premier site avec ASP.NET 5

Maintenant que nous avons terminé notre première approche des différents outils de l’environnement ASP.nET 5, nous allons pouvoir commencer à écrire une première application Web.

Dans un premier temps, nous allons faire très simple : répondre à des requêtes HTTP en retournant une chaine de caractère en dur. La première étape consiste à préparer le serveur que notre application doit utiliser. Pour faire simple, nous allons prendre un simple listener HTTP. Faîtes les modifications suivantes dans votre fichier project.json. J’ai ajouté une commande qui va nous permettre de démarrer le listener sur un port spécifique. Notez également que j’ai ajouté une dépendance sur un nouveau paquet.

{
    "dependencies": {
        "Microsoft.AspNet.Hosting": "1.0.0-beta1",
        "Microsoft.AspNet.Server.WebListener": "1.0.0-beta1"
    },
    "commands":{
        "web" : "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:2626/"
    }
}

Dans un second temps, supprimez la classe Program.cs de votre projet et ajoutez une classe Startup.cs. Copiez-y l’exemple de code ci-dessous. Notez que le nom de la classe et la méthode Configure doivent s’appeler strictement ainsi (convention).Notez également la ressemblance avec l’écriture d’un middleware OWIN / Katana.

using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;

namespace Demo
{
    public class Startup  
    {
        public void Configure(IApplicationBuilder  app)
        {
            app.Run(async context =>
            {
                context.Response.ContentType = "text/plain";
                await context.Response.WriteAsync("Salut :)");        
            });
        }
    }
}

Vous pouvez ensuite simplement démarrer l’application en exécutant les instructions kpm restore puis k web. Il ne reste plus qu’à taper l’adresse http://localhost:2626 dans un navigateur et observer le résultat.

Nous pouvons également utiliser le package Microsoft.AspNet.Diagnostics pour afficher la page de debug que nous connaissions déjà avec Katana et le middleware de diagnostic. Apportez les modifications suivantes à votre projet.

{
    "dependencies": {
        "Microsoft.AspNet.Hosting": "1.0.0-beta1",
        "Microsoft.AspNet.Server.WebListener": "1.0.0-beta1",
        "Microsoft.AspNet.Diagnostics": "1.0.0-beta1"
    },
    "commands":{
        "web" : "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:2626/"
    }
}

using Microsoft.AspNet.Builder;

namespace Demo
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
            app.UseWelcomePage();
        }
    }
}

A nouveau, restaurez les dépendances pour démarrer le listener HTTP. Cette fois ci, en consultant votre application dans un navigateur, vous verrez une page plus complexe apparaître.

Dans mon prochain billet, je vous présenterais les modifications à apporter au projet obtenu à l’issu de ce billet afin d’utiliser MVC 6. Bien évidemment, même si j’ai fait l’intégralité des exemples ci-dessus en partant du postulat que nous développons dans un environnement sans Visual Studio, ne vous privez pas pour autant de l’utiliser ! La version actuellement sortie à la date d’écriture de ce billet intègre plutôt bien les différents outils K. Il est cependant recommandé de l’installer dans une VM ou dans un environnement jetable et d’évider une installation side-by-side avec une version précédente de Visual Studio.

Les ressources sur le sujet

Pour terminer, si le sujet vous intéresse, je vous invite à consulter les ressources suivantes qui vous permettront d’aller plus loin :

A bientôt,

Nombre de vue : 116

COMMENTAIRES 1 commentaire

  1. Philess dit :

    Super billet! Merci

AJOUTER UN COMMENTAIRE