Vue d’ensemble du projet Katana

par Howard Dierking

Le ASP.NET Framework a été mis en place depuis plus de dix ans, et la plateforme a permis le développement d’innombrables sites et services Web. À mesure que les stratégies de développement d’applications web ont évolué, l’infrastructure a pu évoluer en phase avec des technologies telles que ASP.NET MVC et API Web ASP.NET. Alors que le développement d’applications web franchit sa prochaine étape évolutive dans le monde du cloud computing, le projet Katana fournit l’ensemble sous-jacent de composants pour ASP.NET applications, ce qui leur permet d’être flexibles, portables, légers et de fournir de meilleures performances. Autrement dit, le projet Katana cloud optimise vos applications ASP.NET.

Pourquoi Katana – Pourquoi maintenant ?

Qu’il s’agisse d’une infrastructure de développement ou d’un produit utilisateur final, il est important de comprendre les motivations sous-jacentes pour créer le produit, et une partie de cela inclut de savoir pour qui le produit a été créé. ASP.NET a été créé à l’origine avec deux clients à l’esprit.

Le premier groupe de clients était des développeurs ASP classiques. À l’époque, ASP était l’une des principales technologies de création de sites web et d’applications web dynamiques et pilotés par les données en entrelacant le balisage et le script côté serveur. Le runtime ASP a fourni un script côté serveur avec un ensemble d’objets qui a extrait les principaux aspects du protocole HTTP sous-jacent et du serveur Web, et a fourni l’accès à des services supplémentaires tels que la gestion de l’état des sessions et des applications, le cache, etc. Bien que puissantes, les applications ASP classiques sont devenues un défi à gérer à mesure qu’elles ont augmenté en taille et en complexité. Cela était en grande partie dû au manque de structure trouvé dans les environnements de script couplé à la duplication de code résultant de l’entrelacement du code et du balisage. Afin de tirer parti des points forts d’ASP classique tout en répondant à certains de ses défis, ASP.NET a tiré parti du code organization fourni par les langages orientés objet du .NET Framework tout en conservant le modèle de programmation côté serveur auquel les développeurs ASP classiques étaient habitués.

Le deuxième groupe de clients cibles pour ASP.NET était les développeurs d’applications métier Windows. Contrairement aux développeurs ASP classiques, qui étaient habitués à écrire du balisage HTML et du code pour générer plus de balisage HTML, les développeurs WinForms (comme les développeurs VB6 avant eux) étaient habitués à une expérience de conception comprenant un canevas et un ensemble complet de contrôles d’interface utilisateur. La première version de ASP.NET, également appelée « Web Forms », offrait une expérience de conception similaire, ainsi qu’un modèle d’événement côté serveur pour les composants d’interface utilisateur et un ensemble de fonctionnalités d’infrastructure (telles que ViewState) pour créer une expérience de développement transparente entre la programmation côté client et côté serveur. Web Forms masque efficacement la nature sans état du web sous un modèle d’événement avec état familier aux développeurs WinForms.

Défis soulevés par le modèle historique

Le résultat net a été un runtime mature et riche en fonctionnalités et un modèle de programmation pour développeurs. Cependant, avec cette richesse de caractéristiques est venu quelques défis notables. Tout d’abord, le framework était monolithique, avec des unités de fonctionnalités logiquement disparates étroitement couplées dans le même assembly System.Web.dll (par exemple, les objets HTTP principaux avec l’infrastructure Web Forms). Deuxièmement, ASP.NET a été inclus dans le cadre du .NET Framework plus large, ce qui signifie que le temps entre les versions était de l’ordre des années. Cela a rendu difficile pour ASP.NET de suivre le rythme de tous les changements qui se produisent dans le développement web en constante évolution. Enfin, System.Web.dll lui-même a été couplé de différentes façons à une option d’hébergement Web spécifique : Internet Information Services (IIS).

Étapes évolutives : ASP.NET MVC et API Web ASP.NET

Et beaucoup de changements se produisaient dans le développement web ! Les applications web étaient de plus en plus développées sous la forme d’une série de petits composants ciblés plutôt que de grandes infrastructures. Le nombre de composants ainsi que la fréquence à laquelle ils ont été libérés augmentaient à un rythme de plus en plus rapide. Il était clair que le fait de suivre le rythme du web exigerait que les infrastructures soient plus petites, découplées et plus ciblées plutôt que plus grandes et plus riches en fonctionnalités. Par conséquent, l’équipe ASP.NET a pris plusieurs mesures évolutives pour permettre ASP.NET en tant que famille de composants Web enfichables plutôt qu’une seule infrastructure.

L’un des premiers changements a été l’augmentation de la popularité du modèle de conception MVC (Model-View-Controller) bien connu grâce aux frameworks de développement Web comme Ruby on Rails. Ce style de création d’applications web a donné au développeur un plus grand contrôle sur le balisage de son application tout en conservant la séparation du balisage et de la logique métier, qui était l’un des points de vente initiaux pour ASP.NET. Pour répondre à la demande pour ce style de développement d’applications web, Microsoft a profité de l’occasion pour mieux se positionner pour l’avenir en développant ASP.NET MVC hors bande (et ne pas l’inclure dans le .NET Framework). ASP.NET MVC a été publié en téléchargement indépendant. Cela a donné à l’équipe d’ingénierie la flexibilité nécessaire pour fournir des mises à jour beaucoup plus fréquemment qu’auparavant.

Un autre changement majeur dans le développement d’applications web a été le passage de pages Web dynamiques générées par le serveur à un balisage initial statique avec des sections dynamiques de la page générées à partir d’un script côté client communiquant avec les API web back-end via des requêtes AJAX. Ce changement architectural a contribué à l’essor des API web et au développement de l’infrastructure API Web ASP.NET. Comme dans le cas de ASP.NET MVC, la publication de API Web ASP.NET a fourni une autre occasion d’évoluer ASP.NET plus loin en tant que framework plus modulaire. L’équipe d’ingénierie a profité de cette opportunité et a créé API Web ASP.NET de sorte qu’elle n’avait aucune dépendance sur les types de framework de base trouvés dans System.Web.dll. Cela a permis deux choses : tout d’abord, cela signifiait que API Web ASP.NET pouvait évoluer de manière complètement autonome (et continuer à itérer rapidement, car elle est fournie via NuGet). Deuxièmement, étant donné qu’il n’y avait aucune dépendance externe à System.Web.dll et, par conséquent, aucune dépendance à IIS, API Web ASP.NET incluait la possibilité d’exécuter dans un hôte personnalisé (par exemple, une application console, un service Windows, etc.)

L’avenir : une infrastructure agile

En découplant les composants du framework les uns des autres, puis en les libérant sur NuGet, les frameworks peuvent désormais itérer de manière plus indépendante et plus rapide. En outre, la puissance et la flexibilité de la fonctionnalité d’auto-hébergement de l’API web se sont avérées très intéressantes pour les développeurs qui voulaient un petit hôte léger pour leurs services. Il s’est avéré si attrayant, en fait, que d’autres infrastructures voulaient également cette fonctionnalité, et cela a posé un nouveau défi dans la mesure où chaque infrastructure s’exécutait dans son propre processus hôte sur sa propre adresse de base et devait être gérée (démarrée, arrêtée, etc.) indépendamment. Une application web moderne prend généralement en charge le service de fichiers statiques, la génération de pages dynamiques, l’API web et plus récemment les notifications Push/en temps réel. S’attendre à ce que chacun de ces services soit exécuté et géré indépendamment n’était tout simplement pas réaliste.

Ce qui était nécessaire, c’était une abstraction d’hébergement unique qui permettrait à un développeur de composer une application à partir d’une variété de composants et de frameworks différents, puis d’exécuter cette application sur un hôte de prise en charge.

Open Web Interface pour .NET (OWIN)

Inspirés par les avantages obtenus par Rack dans la communauté Ruby, plusieurs membres de la communauté .NET ont décidé de créer une abstraction entre les serveurs Web et les composants du framework. Deux objectifs de conception pour l’abstraction OWIN étaient qu’elle était simple et qu’elle prenait le moins de dépendances possible sur d’autres types d’infrastructure. Ces deux objectifs permettent de garantir :

  • De nouveaux composants pourraient être plus facilement développés et consommés.
  • Les applications peuvent être plus facilement transférées entre des hôtes et des plateformes/systèmes d’exploitation potentiellement entiers.

L’abstraction résultante se compose de deux éléments principaux. Le premier est le dictionnaire d’environnement. Cette structure de données est chargée de stocker tout l’état nécessaire au traitement d’une requête et d’une réponse HTTP, ainsi que tout état de serveur pertinent. Le dictionnaire d’environnement est défini comme suit :

IDictionary<string, object>

Un serveur Web compatible OWIN est chargé de remplir le dictionnaire d’environnement avec des données telles que les flux de corps et les collections d’en-têtes pour une requête et une réponse HTTP. Il incombe ensuite aux composants de l’application ou de l’infrastructure de remplir ou de mettre à jour le dictionnaire avec des valeurs supplémentaires et d’écrire dans le flux de corps de la réponse.

En plus de spécifier le type pour le dictionnaire d’environnement, la spécification OWIN définit une liste de paires de valeurs de clé de dictionnaire principal. Par exemple, le tableau suivant montre les clés de dictionnaire requises pour une requête HTTP :

Nom de la clé Description de la valeur
"owin.RequestBody" Un flux avec le corps de la demande, le cas échéant. Stream.Null PEUT être utilisé comme espace réservé s’il n’y a pas de corps de requête. Consultez Corps de la demande.
"owin.RequestHeaders" d’en-têtes IDictionary<string, string[]> de requête. Consultez En-têtes.
"owin.RequestMethod" string contenant la méthode de requête HTTP de la requête (par exemple, "GET", "POST").
"owin.RequestPath" string contenant le chemin d’accès de la requête. Le chemin d’accès DOIT être relatif à la « racine » du délégué d’application ; consultez Chemins d’accès.
"owin.RequestPathBase" string contenant la partie du chemin d’accès de la requête correspondant à la « racine » du délégué d’application ; consultez Chemins d’accès.
"owin.RequestProtocol" string contenant le nom et la version du protocole (par exemple"HTTP/1.0", ou "HTTP/1.1").
"owin.RequestQueryString" string contenant le composant de chaîne de requête de l’URI de requête HTTP, sans le début « ? » (par exemple, "foo=bar&baz=quux"). La valeur peut être une chaîne vide.
"owin.RequestScheme" string contenant le schéma d’URI utilisé pour la requête (par exemple, "http", "https"). consultez Schéma d’URI.

Le deuxième élément clé d’OWIN est le délégué d’application. Il s’agit d’une signature de fonction qui sert d’interface principale entre tous les composants d’une application OWIN. La définition du délégué d’application est la suivante :

Func<IDictionary<string, object>, Task>;

Le délégué d’application est alors simplement une implémentation du type de délégué Func où la fonction accepte le dictionnaire d’environnement comme entrée et retourne une tâche. Cette conception a plusieurs implications pour les développeurs :

  • Il existe un très petit nombre de dépendances de type requises pour écrire des composants OWIN. Cela augmente considérablement l’accessibilité d’OWIN pour les développeurs.
  • La conception asynchrone permet à l’abstraction d’être efficace avec sa gestion des ressources de calcul, en particulier dans les opérations plus intensives en E/S.
  • Étant donné que le délégué d’application est une unité atomique d’exécution et que le dictionnaire d’environnement est transporté en tant que paramètre sur le délégué, les composants OWIN peuvent être facilement chaînés pour créer des pipelines de traitement HTTP complexes.

Du point de vue de l’implémentation, OWIN est une spécification (http://owin.org/html/owin.html). Son objectif n’est pas d’être le prochain framework Web, mais plutôt une spécification de la façon dont les infrastructures web et les serveurs Web interagissent.

Si vous avez examiné OWIN ou Katana, vous avez peut-être également remarqué le package NuGet Owin et Owin.dll. Cette bibliothèque contient une interface unique, [IAppBuilder]/dotnet/api/microsoft.aspnetcore.builder.iapplicationbuilder), qui formalise et codifie la séquence de démarrage décrite dans la section 4 de la spécification OWIN. Bien qu’elle ne soit pas requise pour générer des serveurs OWIN, l’interface [IAppBuilder]/dotnet/api/microsoft.aspnetcore.builder.iapplicationbuilder) fournit un point de référence concret et est utilisée par les composants du projet Katana.

Projet Katana

Alors que la spécification OWIN et lesOwin.dll appartiennent à la communauté et sont gérés par la communauté open source des efforts, le projet Katana représente l’ensemble des composants OWIN qui, bien qu’encore open source, sont générés et publiés par Microsoft. Ces composants incluent à la fois des composants d’infrastructure, tels que des hôtes et des serveurs, ainsi que des composants fonctionnels, tels que des composants d’authentification et des liaisons à des infrastructures telles que SignalR et API Web ASP.NET. Le projet a les trois objectifs généraux suivants :

  • Portable : les composants doivent pouvoir être facilement substitués aux nouveaux composants à mesure qu’ils deviennent disponibles. Cela inclut tous les types de composants, de l’infrastructure au serveur et à l’hôte. L’implication de cet objectif est que les infrastructures tierces peuvent s’exécuter en toute transparence sur des serveurs Microsoft, tandis que les frameworks Microsoft peuvent potentiellement s’exécuter sur des serveurs et des hôtes tiers.
  • Modulaire/flexible : contrairement à de nombreuses infrastructures qui incluent une myriade de fonctionnalités activées par défaut, les composants du projet Katana doivent être petits et ciblés, ce qui permet au développeur d’applications de contrôler les composants à utiliser dans son application.
  • Léger/performant/scalable : en cassant la notion traditionnelle d’infrastructure en un ensemble de petits composants ciblés qui sont ajoutés explicitement par le développeur d’applications, une application Katana résultante peut consommer moins de ressources informatiques et, par conséquent, gérer plus de charge qu’avec d’autres types de serveurs et d’infrastructures. Comme les exigences de l’application exigent davantage de fonctionnalités de l’infrastructure sous-jacente, celles-ci peuvent être ajoutées au pipeline OWIN, mais cela doit être une décision explicite de la part du développeur de l’application. En outre, la substituabilité des composants de niveau inférieur signifie qu’à mesure qu’ils deviennent disponibles, de nouveaux serveurs hautes performances peuvent être introduits en toute transparence pour améliorer les performances des applications OWIN sans interrompre ces applications.

Prise en main avec les composants Katana

Lorsqu’il a été introduit pour la première fois, l’un des aspects de l’infrastructure Node.js qui a immédiatement attiré l’attention des gens était la simplicité avec laquelle on pouvait créer et exécuter un serveur Web. Si les objectifs katana ont été encadrés à la lumière de Node.js, on pourrait les résumer en disant que Katana apporte un grand nombre des avantages de Node.js (et des frameworks comme celui-ci) sans forcer le développeur à jeter tout ce qu’elle sait sur le développement d’applications web ASP.NET. Pour que cette affirmation soit vraie, la prise en main du projet Katana doit être tout aussi simple à Node.js.

Création de « Hello World! »

Une différence notable entre le développement JavaScript et .NET est la présence (ou l’absence) d’un compilateur. Par conséquent, le point de départ d’un serveur Katana simple est un projet Visual Studio. Toutefois, nous pouvons commencer par les types de projets les plus minimaux : l’application web vide ASP.NET.

Capture d’écran du menu Projet ASP.Net - WebApplication1, montrant comment démarrer le volet fenêtre pour créer un projet « Hello World ». Affiche une fenêtre avec différents modèles à sélectionner et les options permettant d’ajouter des références principales et des tests unitaires.

Ensuite, nous allons installer le package NuGet Microsoft.Owin.Host.SystemWeb dans le projet. Ce package fournit un serveur OWIN qui s’exécute dans le pipeline de requête ASP.NET. Il se trouve dans la galerie NuGet et peut être installé à l’aide de la boîte de dialogue gestionnaire de package Visual Studio ou de la console du gestionnaire de package avec la commande suivante :

install-package Microsoft.Owin.Host.SystemWeb

L’installation du Microsoft.Owin.Host.SystemWeb package installe quelques packages supplémentaires en tant que dépendances. L’une de ces dépendances est Microsoft.Owin, une bibliothèque qui fournit plusieurs types et méthodes d’assistance pour le développement d’applications OWIN. Nous pouvons utiliser ces types pour écrire rapidement le serveur « hello world » suivant.

public class Startup
{
   public void Configuration(IAppBuilder app)
   {
      app.Run(context =>
      {
         context.Response.ContentType = "text/plain";
         return context.Response.WriteAsync("Hello World!");
      });
   }
}

Ce serveur web très simple peut désormais être exécuté à l’aide de la commande F5 de Visual Studio et inclut une prise en charge complète du débogage.

Changement d’hôte

Par défaut, l’exemple « hello world » précédent s’exécute dans le pipeline de requête ASP.NET, qui utilise System.Web dans le contexte d’IIS. Cela peut en soi ajouter une valeur considérable, car il nous permet de bénéficier de la flexibilité et de la composabilité d’un pipeline OWIN avec les fonctionnalités de gestion et la maturité globale d’IIS. Toutefois, il peut y avoir des cas où les avantages fournis par IIS ne sont pas requis et le désir est d’avoir un hôte plus petit et plus léger. Que faut-il donc pour exécuter notre serveur Web simple en dehors d’IIS et de System.Web ?

Pour illustrer l’objectif de portabilité, le passage d’un hôte serveur Web à un hôte de ligne de commande nécessite simplement d’ajouter les nouvelles dépendances de serveur et d’hôte au dossier de sortie du projet, puis de démarrer l’hôte. Dans cet exemple, nous allons héberger notre serveur Web dans un hôte Katana appelé OwinHost.exe et utiliser le serveur HttpListener katana. Comme pour les autres composants Katana, ceux-ci seront acquis à partir de NuGet à l’aide de la commande suivante :

install-package OwinHost

À partir de la ligne de commande, nous pouvons ensuite accéder au dossier racine du projet et exécuter simplement le OwinHost.exe (qui a été installé dans le dossier tools de son package NuGet respectif). Par défaut, est configuré pour rechercher le serveur HttpListener. Par conséquent, OwinHost.exe aucune configuration supplémentaire n’est nécessaire. Navigation dans un navigateur web pour http://localhost:5000/ afficher l’application en cours d’exécution via la console.

Capture d’écran du promt de la commande développeur et de la fenêtre du navigateur, montrant une comparaison des commandes entrées sur la ligne de commande et de ce à quoi ressemblerait le projet « Hello World » dans le navigateur web.

Katana Architecture

L’architecture du composant Katana divise une application en quatre couches logiques, comme illustré ci-dessous : hôte, serveur, intergiciel et application. L’architecture des composants est factorisée de telle sorte que les implémentations de ces couches peuvent être facilement substituées, dans de nombreux cas, sans nécessiter la recompilation de l’application.

Le diagramme des couches architecturales montre quatre barres illustrant les couches logiques dans lesquelles l’architecture de l’application est divisée.

Host

L’hôte est responsable des opérations suivantes :

  • Gestion du processus sous-jacent.

  • Orchestrer le flux de travail qui entraîne la sélection d’un serveur et la construction d’un pipeline OWIN via lequel les requêtes seront gérées.

    À l’heure actuelle, il existe 3 options d’hébergement principales pour les applications basées sur Katana :

IIS/ASP.NET : à l’aide des types HttpModule et HttpHandler standard, les pipelines OWIN peuvent s’exécuter sur IIS dans le cadre d’un flux de requête ASP.NET. ASP.NET prise en charge de l’hébergement est activée en installant le package NuGet Microsoft.AspNet.Host.SystemWeb dans un projet d’application web. En outre, étant donné qu’IIS agit à la fois comme hôte et comme serveur, la distinction serveur/hôte OWIN est confondue dans ce package NuGet, ce qui signifie que si vous utilisez l’hôte SystemWeb, un développeur ne peut pas remplacer une autre implémentation de serveur.

Hôte personnalisé : la suite de composants Katana permet aux développeurs d’héberger des applications dans son propre processus personnalisé, qu’il s’agisse d’une application console, d’un service Windows, etc. Cette fonctionnalité ressemble à la fonctionnalité auto-hôte fournie par l’API web. L’exemple suivant montre un hôte personnalisé de code d’API web :

static void Main()
{
    var baseAddress = new Uri("http://localhost:5000");

    var config = new HttpSelfHostConfiguration(baseAddress);
    config.Routes.MapHttpRoute("default", "{controller}");
       
    using (var svr = new HttpSelfHostServer(config))
    {
        svr.OpenAsync().Wait();
        Console.WriteLine("Press Enter to quit.");
        Console.ReadLine();
    }
}

La configuration de l’auto-hôte pour une application Katana est similaire :

static void Main(string[] args)
{
    const string baseUrl = "http://localhost:5000/";

    using (WebApplication.Start<Startup>(new StartOptions { Url = baseUrl })) 
    {
        Console.WriteLine("Press Enter to quit.");
        Console.ReadKey();
    }
}

Une différence notable entre les exemples d’API web et d’auto-hôte Katana est que le code de configuration de l’API web est manquant dans l’exemple d’auto-hôte Katana. Pour activer à la fois la portabilité et la composabilité, Katana sépare le code qui démarre le serveur du code qui configure le pipeline de traitement des demandes. Le code qui configure l’API web est ensuite contenu dans la classe Startup, qui est également spécifiée en tant que paramètre de type dans WebApplication.Start.

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        config.Routes.MapHttpRoute("default", "{controller}");
        app.UseWebApi(config);
    }
}

La classe de démarrage sera abordée plus en détail plus loin dans l’article. Toutefois, le code requis pour démarrer un processus auto-hôte Katana ressemble étonnamment au code que vous utilisez peut-être aujourd’hui dans API Web ASP.NET applications auto-hôtes.

OwinHost.exe: bien que certains souhaitent écrire un processus personnalisé pour exécuter des applications web Katana, beaucoup préfèrent simplement lancer un exécutable prédéfini qui peut démarrer un serveur et exécuter leur application. Pour ce scénario, la suite de composants Katana inclut OwinHost.exe. Lorsqu’il est exécuté à partir du répertoire racine d’un projet, ce fichier exécutable démarre un serveur (il utilise le serveur HttpListener par défaut) et utilise des conventions pour rechercher et exécuter la classe de démarrage de l’utilisateur. Pour un contrôle plus précis, l’exécutable fournit un certain nombre de paramètres de ligne de commande supplémentaires.

Capture d’écran de l’invite de commandes développeur, montrant un exemple de code de l’invite de commandes lors de l’exécution de l’application sur le serveur.

Serveur

Bien que l’hôte soit responsable du démarrage et de la maintenance du processus dans lequel l’application s’exécute, la responsabilité du serveur est d’ouvrir un socket réseau, d’écouter les requêtes et de les envoyer via le pipeline des composants OWIN spécifiés par l’utilisateur (comme vous l’avez peut-être déjà remarqué, ce pipeline est spécifié dans la classe Startup du développeur de l’application). Actuellement, le projet Katana comprend deux implémentations de serveur :

  • Microsoft.Owin.Host.SystemWeb : comme mentionné précédemment, IIS de concert avec le pipeline ASP.NET agit à la fois comme hôte et comme serveur. Par conséquent, lors du choix de cette option d’hébergement, IIS gère à la fois les problèmes au niveau de l’hôte, tels que l’activation des processus et écoute les requêtes HTTP. Pour ASP.NET applications web, il envoie ensuite les requêtes dans le pipeline ASP.NET. L’hôte Katana SystemWeb inscrit un ASP.NET HttpModule et HttpHandler pour intercepter les requêtes à mesure qu’elles transitent par le pipeline HTTP et les envoyer via le pipeline OWIN spécifié par l’utilisateur.
  • Microsoft.Owin.Host.HttpListener : comme son nom l’indique, ce serveur Katana utilise la classe HttpListener du .NET Framework pour ouvrir un socket et envoyer des requêtes dans un pipeline OWIN spécifié par le développeur. Il s’agit actuellement de la sélection de serveur par défaut pour l’API auto-hôte Katana et OwinHost.exe.

Middleware/framework

Comme mentionné précédemment, lorsque le serveur accepte une demande d’un client, il est chargé de la transmettre via un pipeline de composants OWIN, qui sont spécifiés par le code de démarrage du développeur. Ces composants de pipeline sont appelés intergiciels.
À un niveau très simple, un composant d’intergiciel OWIN doit simplement implémenter le délégué d’application OWIN afin qu’il puisse être appelé.

Func<IDictionary<string, object>, Task>

Toutefois, afin de simplifier le développement et la composition des composants d’intergiciel, Katana prend en charge une poignée de conventions et de types d’assistance pour les composants d’intergiciel. La plus courante d’entre elles est la OwinMiddleware classe . Un composant d’intergiciel personnalisé créé à l’aide de cette classe ressemble à ce qui suit :

public class LoggerMiddleware : OwinMiddleware
{
    private readonly ILog _logger;
 
    public LoggerMiddleware(OwinMiddleware next, ILog logger) : base(next)
    {
        _logger = logger;
    }
 
    public override async Task Invoke(IOwinContext context)
    {
        _logger.LogInfo("Middleware begin");
        await this.Next.Invoke(context);
        _logger.LogInfo("Middleware end");
    }
}

Cette classe dérive de OwinMiddleware, implémente un constructeur qui accepte un instance de l’intergiciel suivant dans le pipeline comme l’un de ses arguments, puis le transmet au constructeur de base. Les arguments supplémentaires utilisés pour configurer l’intergiciel sont également déclarés en tant que paramètres de constructeur après le paramètre d’intergiciel suivant.

Au moment de l’exécution, l’intergiciel est exécuté via la méthode remplacée Invoke . Cette méthode prend un seul argument de type OwinContext. Cet objet de contexte est fourni par le Microsoft.Owin package NuGet décrit précédemment et fournit un accès fortement typé au dictionnaire de requête, de réponse et d’environnement, ainsi qu’à quelques types d’assistance supplémentaires.

La classe middleware peut être facilement ajoutée au pipeline OWIN dans le code de démarrage de l’application comme suit :

public class Startup
{
   public void Configuration(IAppBuilder app)
   {
      app.Use<LoggerMiddleware>(new TraceLogger());

   }
}

Étant donné que l’infrastructure Katana crée simplement un pipeline de composants d’intergiciel OWIN et que les composants ont simplement besoin de prendre en charge le délégué d’application pour participer au pipeline, les composants d’intergiciel peuvent aller de simples enregistreurs d’événements à des frameworks entiers comme ASP.NET, l’API web ou SignalR. Par exemple, l’ajout de API Web ASP.NET au pipeline OWIN précédent nécessite l’ajout du code de démarrage suivant :

public class Startup
{
   public void Configuration(IAppBuilder app)
   {
      app.Use<LoggerMiddleware>(new TraceLogger());

      var config = new HttpConfiguration();
      // configure Web API 
      app.UseWebApi(config);

      // additional middleware registrations            
   }
}

L’infrastructure Katana génère le pipeline des composants d’intergiciel en fonction de l’ordre dans lequel ils ont été ajoutés à l’objet IAppBuilder dans la méthode Configuration. Dans notre exemple, LoggerMiddleware peut gérer toutes les requêtes qui transitent par le pipeline, quelle que soit la façon dont ces requêtes sont finalement gérées. Cela permet de puissants scénarios dans lesquels un composant d’intergiciel (par exemple, un composant d’authentification) peut traiter les demandes d’un pipeline qui inclut plusieurs composants et infrastructures (par exemple, API Web ASP.NET, SignalR et un serveur de fichiers statique).

Applications

Comme l’illustrent les exemples précédents, OWIN et le projet Katana ne doivent pas être considérés comme un nouveau modèle de programmation d’application, mais plutôt comme une abstraction pour dissocier les frameworks et les modèles de programmation d’applications du serveur et de l’infrastructure d’hébergement. Par exemple, lors de la création d’applications d’API web, l’infrastructure de développement continue d’utiliser l’infrastructure API Web ASP.NET, que l’application s’exécute ou non dans un pipeline OWIN à l’aide de composants du projet Katana. Le seul endroit où le code lié à OWIN sera visible par le développeur d’application sera le code de démarrage de l’application, où le développeur compose le pipeline OWIN. Dans le code de démarrage, le développeur inscrit une série d’instructions UseXx, généralement une pour chaque composant d’intergiciel qui traite les demandes entrantes. Cette expérience aura le même effet que l’inscription de modules HTTP dans le monde System.Web actuel. En règle générale, un intergiciel d’infrastructure plus volumineux, tel que API Web ASP.NET ou SignalR, est inscrit à la fin du pipeline. Les composants intergiciels transversaux, tels que ceux pour l’authentification ou la mise en cache, sont généralement inscrits au début du pipeline afin qu’ils traitent les demandes pour tous les frameworks et composants inscrits ultérieurement dans le pipeline. Cette séparation des composants intergiciels entre eux et des composants d’infrastructure sous-jacents permet aux composants d’évoluer à différentes vitesses tout en garantissant que l’ensemble du système reste stable.

Composants – Packages NuGet

À l’instar de nombreuses bibliothèques et infrastructures actuelles, les composants du projet Katana sont fournis sous la forme d’un ensemble de packages NuGet. Pour la prochaine version 2.0, le package Katana graphe des dépendances se présente comme suit. (Cliquez sur l’image pour l’agrandir.)

Diagramme de la hiérarchie composants - packages NuGet. Cette image représente les arborescences de bibliothèques dans lesquelles les infrastructures sont connectées pour les composants du projet et sont livrées via un ensemble de NuGets.

Presque tous les packages du projet Katana dépendent, directement ou indirectement, du package Owin. Vous vous souvenez peut-être qu’il s’agit du package qui contient l’interface IAppBuilder, qui fournit une implémentation concrète de la séquence de démarrage de l’application décrite dans la section 4 de la spécification OWIN. En outre, la plupart des packages dépendent de Microsoft.Owin, qui fournit un ensemble de types d’assistance pour l’utilisation des requêtes et des réponses HTTP. Le reste du package peut être classé comme des packages d’infrastructure d’hébergement (serveurs ou hôtes) ou comme middleware. Les packages et les dépendances externes au projet Katana sont affichés en orange.

L’infrastructure d’hébergement de Katana 2.0 comprend à la fois les serveurs SystemWeb et HttpListener, le package OwinHost pour exécuter des applications OWIN à l’aide de OwinHost.exe et le package Microsoft.Owin.Hosting pour l’auto-hébergement d’applications OWIN dans un hôte personnalisé (par exemple, application console, service Windows, etc.)

Pour Katana 2.0, les composants d’intergiciel sont principalement axés sur la fourniture de différents moyens d’authentification. Un composant intergiciel supplémentaire pour diagnostics est fourni, ce qui permet la prise en charge d’une page de démarrage et d’erreur. À mesure qu’OWIN devient l’abstraction d’hébergement de facto, l’écosystème des composants d’intergiciels, à la fois ceux développés par Microsoft et par des tiers, augmentera également en nombre.

Conclusion

Depuis le début, l’objectif du projet Katana n’a pas été de créer et donc de forcer les développeurs à apprendre encore une autre infrastructure web. Au lieu de cela, l’objectif a été de créer une abstraction pour donner aux développeurs d’applications web .NET plus de choix qu’auparavant. En fractionnant les couches logiques d’une pile d’applications web standard en un ensemble de composants remplaçables, le projet Katana permet aux composants de l’ensemble de la pile de s’améliorer à toute vitesse appropriée pour ces composants. En créant tous les composants autour de l’abstraction OWIN simple, Katana permet aux frameworks et aux applications qui s’appuient sur eux d’être portables sur différents serveurs et hôtes. En plaçant le développeur en contrôle de la pile, Katana s’assure que le développeur fait le choix ultime de la légèreté ou de la richesse de sa pile web.

Pour plus d’informations sur Katana

Remerciements