Share via


Panoramica del progetto Katana

di Howard Dierking

Il framework ASP.NET è stato intorno da oltre dieci anni e la piattaforma ha consentito lo sviluppo di innumerevoli siti Web e servizi. Man mano che si sono sviluppate strategie di sviluppo di applicazioni Web, il framework è stato in grado di evolversi in passo con tecnologie come ASP.NET MVC e API Web ASP.NET. Man mano che lo sviluppo di applicazioni Web entra nel mondo del cloud computing, il progetto Katana fornisce il set sottostante di componenti per ASP.NET applicazioni, consentendo loro di essere flessibili, portatili, leggeri e offrono prestazioni migliori, offrendo un altro modo, proiettare Katana cloud ottimizza le applicazioni ASP.NET.

Perché Katana – Perché ora?

Indipendentemente dal fatto che si stia parlando di un framework di sviluppo o di un prodotto dell'utente finale, è importante comprendere le motivazioni sottostanti per la creazione del prodotto e parte di ciò include la conoscenza dell'utente per cui è stato creato il prodotto. ASP.NET è stato originariamente creato con due clienti in mente.

Il primo gruppo di clienti è stato sviluppatore ASP classico. Al momento, ASP era una delle tecnologie principali per la creazione di siti Web e applicazioni dinamici basati sui dati tramite markup e script lato server. Il runtime ASP ha fornito uno script sul lato server con un set di oggetti che astratte gli aspetti principali del protocollo HTTP sottostante e del server Web e ha fornito l'accesso a servizi aggiuntivi, ad esempio la gestione dello stato dell'applicazione, la cache e così via. Anche se le applicazioni ASP classiche sono diventate una sfida per la gestione man mano che sono cresciute di dimensioni e complessità. Ciò è dovuto in gran parte alla mancanza di struttura trovata negli ambienti di scripting associati alla duplicazione del codice risultante dall'interleaving del codice e del markup. Al fine di sfruttare i punti di forza di ASP classico affrontando alcune delle sue sfide, ASP.NET ha sfruttato l'organizzazione del codice fornita dai linguaggi orientati agli oggetti di .NET Framework mantenendo anche il modello di programmazione lato server a cui gli sviluppatori ASP classici erano cresciuti.

Il secondo gruppo di clienti di destinazione per ASP.NET è stato sviluppatore di applicazioni aziendali di Windows. A differenza degli sviluppatori ASP classici, abituati a scrivere markup HTML e al codice per generare più markup HTML, gli sviluppatori WinForms (come gli sviluppatori VB6 prima di loro) erano abituati a un'esperienza in fase di progettazione che includeva un canvas e un set completo di controlli dell'interfaccia utente. La prima versione di ASP.NET, nota anche come "Web Forms" offre un'esperienza di progettazione simile insieme a un modello di evento lato server per i componenti dell'interfaccia utente e un set di funzionalità dell'infrastruttura (ad esempio ViewState) per creare un'esperienza di sviluppo uniforme tra la programmazione lato client e server. Web Forms nascondeva in modo efficace la natura senza stato del Web con un modello di evento con stato familiare agli sviluppatori WinForms.

Sfide generate dal modello cronologico

Il risultato netto è stato un modello di programmazione sviluppatore e avanzato per le funzionalità. Tuttavia, con questa ricchezza caratteristica è venuto un paio di sfide rilevanti. In primo luogo, il framework era monolitico, con unità logicamente diverse di funzionalità strettamente associate nello stesso assembly System.Web.dll (ad esempio, gli oggetti HTTP principali con il framework Web form). In secondo luogo, ASP.NET è stato incluso come parte di .NET Framework più grande, il che significava che il tempo tra le versioni era nell'ordine di anni. Ciò ha reso difficile per ASP.NET tenere il passo con tutte le modifiche apportate nello sviluppo Web in rapida evoluzione. Infine, System.Web.dll stesso è stato associato in diversi modi per un'opzione di hosting Web specifica: Internet Information Services (IIS).

Passaggi evolutivi: ASP.NET MVC e API Web ASP.NET

E molti cambiamenti sono stati apportati nello sviluppo Web! Le applicazioni Web sono state sempre più sviluppate come una serie di componenti piccoli e incentrati anziché framework di grandi dimensioni. Il numero di componenti e la frequenza con cui sono stati rilasciati è aumentato a una velocità sempre più veloce. Era chiaro che mantenere il ritmo con il Web richiederebbe che i framework siano più piccoli, disaccoppiati e più concentrati piuttosto che più grandi e più ricchi di funzionalità, quindi il team ASP.NET ha adottato diversi passaggi evolutivi per consentire ASP.NET come famiglia di componenti Web collegabili anziché un singolo framework.

Uno dei primi cambiamenti è stato l'aumento della popolarità del noto modello di progettazione MVC (Model-View-Controller) grazie a framework di sviluppo Web come Ruby on Rails. Questo stile di creazione di applicazioni Web ha dato allo sviluppatore un maggiore controllo sul markup dell'applicazione mantenendo comunque la separazione del markup e della logica di business, uno dei punti di vendita iniziali per ASP.NET. Per soddisfare la richiesta di questo stile di sviluppo di applicazioni Web, Microsoft ha avuto l'opportunità di posizionarsi meglio per il futuro sviluppando ASP.NET MVC fuori banda (e non includerlo in .NET Framework). ASP.NET MVC è stato rilasciato come download indipendente. Questo ha dato al team di progettazione la flessibilità di fornire aggiornamenti molto più frequentemente di quanto fosse stato possibile in precedenza.

Un altro importante cambiamento nello sviluppo di applicazioni Web è stato il passaggio dalle pagine Web dinamiche generate dal server al markup iniziale statico con sezioni dinamiche della pagina generate dallo script lato client che comunicano con le API Web back-end tramite richieste AJAX. Questo cambiamento di architettura ha contribuito a spingere l'aumento delle API Web e lo sviluppo del framework API Web ASP.NET. Come nel caso di ASP.NET MVC, la versione di API Web ASP.NET ha offerto un'altra opportunità per evolvere ASP.NET ulteriormente come framework più modulare. Il team di progettazione ha sfruttato l'opportunità e creato API Web ASP.NET in modo che non avesse dipendenze da nessuno dei tipi di framework di base presenti in System.Web.dll. Ciò ha consentito due cose: in primo luogo, significava che API Web ASP.NET potrebbe evolversi in modo completamente autonomo (e potrebbe continuare a scorrere rapidamente perché viene distribuito tramite NuGet). In secondo luogo, poiché non sono presenti dipendenze esterne da System.Web.dll e pertanto nessuna dipendenza da IIS, API Web ASP.NET incluso la funzionalità di esecuzione in un host personalizzato (ad esempio, un'applicazione console, un servizio Windows e così via).

The Future: A Nimble Framework

Separando i componenti del framework l'uno dall'altro e rilasciandoli in NuGet, i framework ora possono eseguire l'iterazione in modo più indipendente e più rapido. Inoltre, la potenza e la flessibilità della funzionalità di self-hosting dell'API Web si sono rivelate molto interessanti per gli sviluppatori che volevano un piccolo host leggero per i propri servizi. Si è dimostrato così interessante, infatti, che altri framework volevano anche questa funzionalità, e ciò ha rivelato una nuova sfida in quanto ogni framework è stato eseguito nel proprio processo host in un proprio indirizzo di base e doveva essere gestito (avviato, arrestato e così via) indipendentemente. Un'applicazione Web moderna supporta in genere la gestione di file statici, la generazione di pagine dinamiche, l'API Web e le notifiche push in tempo reale più di recente. Si prevede che ognuno di questi servizi debba essere eseguito e gestito in modo indipendente non fosse semplicemente realistico.

Ciò che era necessario era un'unica astrazione di hosting che consente a uno sviluppatore di comporre un'applicazione da un'ampia gamma di componenti e framework diversi e quindi eseguire tale applicazione in un host di supporto.

Open Web Interface for .NET (OWIN)

Ispirato ai vantaggi ottenuti da Rack nella community ruby, diversi membri della community .NET hanno definito per creare un'astrazione tra i server Web e i componenti del framework. Due obiettivi di progettazione per l'astrazione OWIN erano che era semplice e che ha impiegato il minor numero possibile di dipendenze da altri tipi di framework. Questi due obiettivi consentono di garantire:

  • I nuovi componenti potrebbero essere più facilmente sviluppati e utilizzati.
  • Le applicazioni possono essere convertite più facilmente tra host e potenzialmente intere piattaforme/sistemi operativi.

L'astrazione risultante è costituita da due elementi principali. Il primo è il dizionario dell'ambiente. Questa struttura di dati è responsabile dell'archiviazione di tutti gli stati necessari per l'elaborazione di una richiesta e una risposta HTTP, nonché di qualsiasi stato del server pertinente. Il dizionario dell'ambiente è definito come segue:

IDictionary<string, object>

Un server Web compatibile con OWIN è responsabile del popolamento del dizionario dell'ambiente con dati quali i flussi del corpo e le raccolte di intestazioni per una richiesta e una risposta HTTP. È quindi responsabilità dell'applicazione o dei componenti del framework popolare o aggiornare il dizionario con valori aggiuntivi e scrivere nel flusso del corpo della risposta.

Oltre a specificare il tipo per il dizionario dell'ambiente, la specifica OWIN definisce un elenco di coppie chiave del dizionario di base. La tabella seguente, ad esempio, mostra le chiavi del dizionario necessarie per una richiesta HTTP:

Nome chiave Descrizione valore
"owin.RequestBody" Oggetto Stream con il corpo della richiesta, se presente. Stream.Null PUÒ essere usato come segnaposto se non è presente alcun corpo della richiesta. Vedere Corpo della richiesta.
"owin.RequestHeaders" Oggetto IDictionary<string, string[]> di intestazioni di richiesta. Vedere Intestazioni.
"owin.RequestMethod" Oggetto string contenente il metodo di richiesta HTTP della richiesta (ad esempio, "GET", "POST").
"owin.RequestPath" Oggetto string contenente il percorso della richiesta. Il percorso DEVE essere relativo alla "radice" del delegato dell'applicazione; vedere Percorsi.
"owin.RequestPathBase" Oggetto string contenente la parte del percorso della richiesta corrispondente alla "radice" del delegato dell'applicazione. Vedere Percorsi.
"owin.RequestProtocol" Oggetto string contenente il nome e la versione del protocollo ,ad esempio "HTTP/1.0" o "HTTP/1.1".
"owin.RequestQueryString" Oggetto string contenente il componente della stringa di query dell'URI della richiesta HTTP, senza l'iniziale "?" (ad esempio, "foo=bar&baz=quux"). Il valore può essere una stringa vuota.
"owin.RequestScheme" Oggetto string contenente lo schema URI usato per la richiesta ( ad esempio "http", ), "https"vedere Schema URI.

Il secondo elemento chiave di OWIN è il delegato dell'applicazione. Si tratta di una firma di funzione che funge da interfaccia principale tra tutti i componenti in un'applicazione OWIN. La definizione per il delegato dell'applicazione è la seguente:

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

Il delegato dell'applicazione è semplicemente un'implementazione del tipo delegato Func in cui la funzione accetta il dizionario dell'ambiente come input e restituisce un'attività. Questa progettazione ha diverse implicazioni per gli sviluppatori:

  • Per scrivere componenti OWIN, è necessario un numero molto ridotto di dipendenze di tipo. Questo aumenta notevolmente l'accessibilità di OWIN agli sviluppatori.
  • La progettazione asincrona consente all'astrazione di essere efficiente con la gestione delle risorse di calcolo, in particolare nelle operazioni più complesse di I/O.
  • Poiché il delegato dell'applicazione è un'unità atomica di esecuzione e poiché il dizionario di ambiente viene trasportato come parametro nel delegato, i componenti OWIN possono essere facilmente concatenati per creare pipeline di elaborazione HTTP complesse.

Dal punto di vista dell'implementazione, OWIN è una specifica (http://owin.org/html/owin.html). L'obiettivo non è quello di essere il framework Web successivo, ma piuttosto una specifica per il modo in cui interagiscono i framework Web e i server Web.

Se hai esaminato OWIN o Katana, potresti aver notato anche il pacchetto NuGet Owin e Owin.dll. Questa libreria contiene una singola interfaccia, [IAppBuilder]/dotnet/api/microsoft.aspnetcore.builder.iapplicationbuilder), che formalizza e codifica la sequenza di avvio descritta nella sezione 4 della specifica OWIN. Anche se non è necessario per compilare server OWIN, l'interfaccia [IAppBuilder]/dotnet/api/microsoft.aspnetcore.builder.iapplicationbuilder) fornisce un punto di riferimento concreto e viene usato dai componenti del progetto Katana.

Project Katana

Mentre sia la specifica OWIN che Owin.dll sono di proprietà della community e vengono eseguite open source sforzi, il progetto Katana rappresenta il set di componenti OWIN che, pur open source, vengono compilati e rilasciati da Microsoft. Questi componenti includono sia componenti dell'infrastruttura, ad esempio host e server, sia componenti funzionali, ad esempio componenti di autenticazione e associazioni a framework come SignalR e API Web ASP.NET. Il progetto ha i tre obiettivi generali seguenti:

  • Portabile : i componenti devono essere facilmente sostituiti per i nuovi componenti non appena diventano disponibili. Sono inclusi tutti i tipi di componenti, dal framework al server e all'host. L'implicazione di questo obiettivo è che i framework di terze parti possono essere eseguiti facilmente nei server Microsoft, mentre i framework Microsoft possono potenzialmente essere eseguiti su server e host di terze parti.
  • Modulare/flessibile: a differenza di molti framework che includono una miriade di funzionalità attivate per impostazione predefinita, i componenti del progetto Katana devono essere piccoli e concentrati, dando il controllo allo sviluppatore dell'applicazione per determinare i componenti da usare nell'applicazione.
  • Leggero/efficiente/scalabile : suddividendo la nozione tradizionale di un framework in un set di componenti piccoli e incentrati che vengono aggiunti in modo esplicito dallo sviluppatore dell'applicazione, un'applicazione Katana risultante può utilizzare meno risorse di calcolo e, di conseguenza, gestire più carico, rispetto ad altri tipi di server e framework. Poiché i requisiti dell'applicazione richiedono più funzionalità dall'infrastruttura sottostante, tali funzionalità possono essere aggiunte alla pipeline OWIN, ma che devono essere una decisione esplicita nell'ambito dello sviluppatore di applicazioni. Inoltre, la sostituzione dei componenti di livello inferiore significa che, man mano che diventano disponibili, i nuovi server ad alte prestazioni possono essere introdotti senza problemi per migliorare le prestazioni delle applicazioni OWIN senza interrompere tali applicazioni.

Introduzione con i componenti Katana

Quando è stata introdotta per la prima volta, un aspetto del framework Node.js che ha immediatamente richiamato l'attenzione delle persone è stata la semplicità con cui è possibile creare ed eseguire un server Web. Se gli obiettivi di Katana sono stati inquadrati in luce diNode.js, uno potrebbe riepilogarli dicendo che Katana porta molti dei vantaggi di Node.js(e framework come esso) senza forzare lo sviluppatore di generare tutto quello che sa sullo sviluppo di applicazioni Web ASP.NET. Per mantenere true questa istruzione, iniziare con il progetto Katana deve essere altrettanto semplice in natura per Node.js.

Creazione di "Hello World!"

Una differenza notevole tra lo sviluppo JavaScript e .NET è la presenza (o l'assenza) di un compilatore. Di conseguenza, il punto di partenza per un semplice server Katana è un progetto di Visual Studio. Tuttavia, è possibile iniziare con il più minimo di tipi di progetto: l'applicazione Web vuota ASP.NET.

Screenshot del menu Project - WebApplication1 ASP.Net, che illustra come creare un progetto

Verrà quindi installato il pacchetto NuGet Microsoft.Owin.Host.SystemWeb nel progetto. Questo pacchetto fornisce un server OWIN che viene eseguito nella pipeline di richiesta di ASP.NET. È possibile trovare nella raccolta NuGet e può essere installato usando la finestra di dialogo Gestione pacchetti di Visual Studio o la console di gestione pacchetti con il comando seguente:

install-package Microsoft.Owin.Host.SystemWeb

L'installazione del Microsoft.Owin.Host.SystemWeb pacchetto installerà alcuni pacchetti aggiuntivi come dipendenze. Una di queste dipendenze è Microsoft.Owin, una libreria che fornisce diversi tipi e metodi helper per lo sviluppo di applicazioni OWIN. È possibile usare questi tipi per scrivere rapidamente il server "hello world" seguente.

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

Questo server Web molto semplice può ora essere eseguito usando il comando F5 di Visual Studio e include il supporto completo per il debug.

Passaggio di host

Per impostazione predefinita, l'esempio precedente "hello world" viene eseguito nella pipeline di richiesta ASP.NET, che usa System.Web nel contesto di IIS. Ciò può anche aggiungere un valore enorme perché consente di trarre vantaggio dalla flessibilità e dalla componibilità di una pipeline OWIN con le funzionalità di gestione e la maturità complessiva di IIS. Tuttavia, potrebbero esserci casi in cui i vantaggi offerti da IIS non sono necessari e il desiderio è per un host più piccolo e più leggero. Quali sono le esigenze, quindi, per eseguire il semplice server Web all'esterno di IIS e System.Web?

Per illustrare l'obiettivo di portabilità, lo spostamento da un host server Web a un host della riga di comando richiede semplicemente l'aggiunta del nuovo server e delle dipendenze host alla cartella di output del progetto e quindi all'avvio dell'host. In questo esempio il server Web verrà ospitato in un host Katana denominato OwinHost.exe e userà il server basato su Katana HttpListener. Analogamente agli altri componenti Katana, questi verranno acquisiti da NuGet usando il comando seguente:

install-package OwinHost

Dalla riga di comando, è quindi possibile passare alla cartella radice del progetto ed eseguire semplicemente ( OwinHost.exe che è stata installata nella cartella degli strumenti del rispettivo pacchetto NuGet). Per impostazione predefinita, OwinHost.exe è configurato per cercare il server basato su HttpListener e quindi non è necessaria alcuna configurazione aggiuntiva. Spostamento in un Web browser per http://localhost:5000/ visualizzare l'applicazione in esecuzione tramite la console.

Screenshot della finestra Comando sviluppatore Promt e del browser, che mostra un confronto dei comandi immessi nella riga di comando e quello che il progetto 'Hello World' sarà simile al Web browser.

Architettura di Katana

L'architettura del componente Katana divide un'applicazione in quattro livelli logici, come illustrato di seguito: host, server, middleware e applicazione. L'architettura del componente è considerata in modo tale che le implementazioni di questi livelli possano essere facilmente sostituite, in molti casi, senza richiedere la ricompilazione dell'applicazione.

Diagramma dei livelli architetturali che mostra\ing quattro barre che illustrano i livelli logici in cui l'architettura dell'applicazione è divisa.

Host

L'host è responsabile di:

  • Gestione del processo sottostante.

  • Orchestrazione del flusso di lavoro che comporta la selezione di un server e la costruzione di una pipeline OWIN tramite cui verranno gestite le richieste.

    Attualmente sono disponibili 3 opzioni di hosting primarie per le applicazioni basate su Katana:

IIS/ASP.NET: usando i tipi HttpModule e HttpHandler standard, le pipeline OWIN possono essere eseguite in IIS come parte di un flusso di richiesta ASP.NET. ASP.NET supporto per l'hosting è abilitato installando il pacchetto NuGet Microsoft.AspNet.Host.SystemWeb in un progetto di applicazione Web. Inoltre, poiché IIS funge sia da host che da server, la distinzione del server/host OWIN viene conflizionata in questo pacchetto NuGet, ovvero se si usa l'host SystemWeb, uno sviluppatore non può sostituire un'implementazione del server alternativa.

Host personalizzato: la suite di componenti Katana offre agli sviluppatori la possibilità di ospitare applicazioni nel proprio processo personalizzato, indipendentemente dal fatto che sia un'applicazione console, un servizio Windows e così via. Questa funzionalità è simile alla funzionalità self-host fornita dall'API Web. Nell'esempio seguente viene illustrato un host personalizzato di codice 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 configurazione self-host per un'applicazione Katana è simile:

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();
    }
}

Una differenza notevole tra l'API Web e gli esempi self-host di Katana è che il codice di configurazione dell'API Web manca dall'esempio self-host Katana. Per abilitare la portabilità e la componibilità, Katana separa il codice che avvia il server dal codice che configura la pipeline di elaborazione delle richieste. Il codice che configura l'API Web, quindi è contenuto nella classe Startup, che viene inoltre specificato come parametro di tipo in WebApplication.Start.

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

La classe di avvio verrà illustrata in dettaglio più avanti nell'articolo. Tuttavia, il codice necessario per avviare un processo self-host Katana sembra sorprendentemente simile al codice che si può usare oggi in API Web ASP.NET applicazioni self-host.

OwinHost.exe: mentre alcuni vogliono scrivere un processo personalizzato per eseguire applicazioni Web Katana, molti preferiscono semplicemente avviare un eseguibile predefinito che può avviare un server ed eseguire l'applicazione. Per questo scenario, la suite di componenti Katana include OwinHost.exe. Quando viene eseguito dall'interno della directory radice di un progetto, questo eseguibile avvierà un server (usa il server HttpListener per impostazione predefinita) e userà convenzioni per trovare ed eseguire la classe di avvio dell'utente. Per un controllo più granulare, l'eseguibile fornisce un numero di parametri aggiuntivi della riga di comando.

Screenshot del prompt dei comandi per sviluppatori, che mostra un esempio del codice del prompt dei comandi durante l'esecuzione dell'applicazione nel server.

Server

Sebbene l'host sia responsabile dell'avvio e della gestione del processo in cui viene eseguita l'applicazione, la responsabilità del server consiste nell'aprire un socket di rete, ascoltare le richieste e inviarle tramite la pipeline dei componenti OWIN specificati dall'utente (come si potrebbe già notare, questa pipeline viene specificata nella classe Startup dello sviluppatore dell'applicazione). Attualmente, il progetto Katana include due implementazioni del server:

  • Microsoft.Owin.Host.SystemWeb: come indicato in precedenza, IIS in concerto con la pipeline di ASP.NET funge sia da host che da server. Pertanto, quando si sceglie questa opzione di hosting, IIS gestisce entrambi i problemi a livello di host, ad esempio l'attivazione del processo e l'ascolto delle richieste HTTP. Per ASP.NET applicazioni Web, invia quindi le richieste nella pipeline di ASP.NET. L'host Katana SystemWeb registra un ASP.NET HttpModule e HttpHandler per intercettare le richieste durante il flusso tramite la pipeline HTTP e inviarle tramite la pipeline OWIN specificata dall'utente.
  • Microsoft.Owin.Host.HttpListener: come indica il nome, questo server Katana usa la classe HttpListener di .NET Framework per aprire un socket e inviare richieste in una pipeline OWIN specificata dallo sviluppatore. Questa è attualmente la selezione del server predefinita per l'API self-host Katana e OwinHost.exe.

Middleware/framework

Come accennato in precedenza, quando il server accetta una richiesta da un client, è responsabile del passaggio tramite una pipeline di componenti OWIN, specificati dal codice di avvio dello sviluppatore. Questi componenti della pipeline sono noti come middleware.
A livello molto semplice, un componente middleware OWIN deve semplicemente implementare il delegato dell'applicazione OWIN in modo che sia chiamabile.

Func<IDictionary<string, object>, Task>

Tuttavia, per semplificare lo sviluppo e la composizione dei componenti middleware, Katana supporta una manciata di convenzioni e tipi helper per i componenti middleware. Il più comune di questi è la OwinMiddleware classe . Un componente middleware personalizzato compilato usando questa classe sarà simile al seguente:

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");
    }
}

Questa classe deriva da OwinMiddleware, implementa un costruttore che accetta un'istanza del middleware successivo nella pipeline come uno dei relativi argomenti e quindi lo passa al costruttore di base. Gli argomenti aggiuntivi usati per configurare il middleware vengono dichiarati anche come parametri del costruttore dopo il parametro middleware successivo.

In fase di esecuzione, il middleware viene eseguito tramite il metodo sottoposto a override Invoke . Questo metodo accetta un singolo argomento di tipo OwinContext. Questo oggetto di contesto viene fornito dal pacchetto NuGet descritto in precedenza e fornisce l'accesso Microsoft.Owin fortemente tipizzato al dizionario di richiesta, risposta e ambiente, oltre a alcuni tipi di helper aggiuntivi.

La classe middleware può essere facilmente aggiunta alla pipeline OWIN nel codice di avvio dell'applicazione come indicato di seguito:

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

   }
}

Poiché l'infrastruttura Katana crea semplicemente una pipeline di componenti middleware OWIN e perché i componenti devono semplicemente supportare il delegato dell'applicazione per partecipare alla pipeline, i componenti middleware possono variare in complessità da semplici loggers a interi framework come ASP.NET, API Web o SignalR. Ad esempio, l'aggiunta di API Web ASP.NET alla pipeline OWIN precedente richiede l'aggiunta del codice di avvio seguente:

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'infrastruttura Katana creerà la pipeline di componenti middleware in base all'ordine in cui sono stati aggiunti all'oggetto IAppBuilder nel metodo Configuration. In questo esempio, LoggerMiddleware può gestire tutte le richieste che passano attraverso la pipeline, indipendentemente dal modo in cui tali richieste vengono gestite. Ciò consente scenari avanzati in cui un componente middleware (ad esempio un componente di autenticazione) può elaborare le richieste per una pipeline che include più componenti e framework (ad esempio API Web ASP.NET, SignalR e un file server statico).

Applicazioni

Come illustrato dagli esempi precedenti, OWIN e il progetto Katana non devono essere considerati come un nuovo modello di programmazione dell'applicazione, ma piuttosto come astrazione per separare i modelli di programmazione delle applicazioni e i framework dal server e dall'infrastruttura di hosting. Ad esempio, quando si creano applicazioni API Web, il framework di sviluppo continuerà a usare il framework di API Web ASP.NET, indipendentemente dal fatto che l'applicazione venga eseguita in una pipeline OWIN usando componenti del progetto Katana. L'unica posizione in cui il codice correlato a OWIN sarà visibile allo sviluppatore dell'applicazione sarà il codice di avvio dell'applicazione, in cui lo sviluppatore compone la pipeline OWIN. Nel codice di avvio lo sviluppatore registrerà una serie di istruzioni UseXx, in genere una per ogni componente middleware che elabora le richieste in ingresso. Questa esperienza avrà lo stesso effetto della registrazione dei moduli HTTP nel mondo System.Web corrente. In genere, un middleware del framework più grande, ad esempio API Web ASP.NET o SignalR, verrà registrato alla fine della pipeline. I componenti middleware incrociati, ad esempio quelli per l'autenticazione o la memorizzazione nella cache, vengono generalmente registrati all'inizio della pipeline in modo da elaborare le richieste per tutti i framework e i componenti registrati più avanti nella pipeline. Questa separazione dei componenti middleware tra loro e dai componenti dell'infrastruttura sottostanti consente ai componenti di evolversi a velocità diverse, assicurandosi che il sistema complessivo rimanga stabile.

Componenti - Pacchetti NuGet

Come molte librerie e framework correnti, i componenti del progetto Katana vengono recapitati come set di pacchetti NuGet. Per la versione 2.0 imminente, il grafico delle dipendenze del pacchetto Katana è simile al seguente. Fare clic sull'immagine per una visualizzazione più grande.

Diagramma dei componenti - Gerarchia dei pacchetti NuGet. Questa immagine illustra gli alberi della libreria in cui i framework sono connessi per i componenti del progetto e vengono recapitati tramite un set di NuGet.

Quasi ogni pacchetto nel progetto Katana dipende, direttamente o indirettamente, dal pacchetto Owin. È possibile ricordare che si tratta del pacchetto che contiene l'interfaccia IAppBuilder, che fornisce un'implementazione concreta della sequenza di avvio dell'applicazione descritta nella sezione 4 della specifica OWIN. Inoltre, molti dei pacchetti dipendono da Microsoft.Owin, che fornisce un set di tipi helper per l'uso di richieste e risposte HTTP. Il resto del pacchetto può essere classificato come hosting di pacchetti di infrastruttura (server o host) o middleware. I pacchetti e le dipendenze esterni al progetto Katana vengono visualizzati in arancione.

L'infrastruttura di hosting per Katana 2.0 include sia i server basati su SystemWeb che HttpListener, il pacchetto OwinHost per l'esecuzione di applicazioni OWIN usando OwinHost.exe e il pacchetto Microsoft.Owin.Hosting per le applicazioni OWIN self-hosting in un host personalizzato ,ad esempio l'applicazione console, il servizio Windows e così via.

Per Katana 2.0, i componenti middleware sono principalmente incentrati sull'offerta di mezzi diversi di autenticazione. Viene fornito un componente middleware aggiuntivo per la diagnostica, che consente il supporto per una pagina iniziale e di errore. Man mano che OWIN cresce nell'astrazione dei fatti, l'ecosistema di componenti middleware, sia quelli sviluppati da Microsoft che da terze parti, cresceranno anche nel numero.

Conclusione

Dall'inizio, l'obiettivo del progetto Katana non è stato quello di creare e quindi forzare gli sviluppatori a imparare ancora un altro framework Web. Invece, l'obiettivo è stato quello di creare un'astrazione per offrire agli sviluppatori di applicazioni Web .NET più scelta di quanto sia stato possibile in precedenza. Suddividendo i livelli logici di uno stack tipico di applicazioni Web in un set di componenti sostituibili, il progetto Katana consente ai componenti in tutto lo stack di migliorare a qualsiasi frequenza abbia senso per tali componenti. Creando tutti i componenti intorno alla semplice astrazione OWIN, Katana consente ai framework e alle applicazioni basate su di esse di essere portabili in un'ampia gamma di server e host diversi. Inserendo lo sviluppatore nel controllo dello stack, Katana garantisce che lo sviluppatore faccia la scelta più semplice o più avanzata dello stack Web.

Per altre informazioni su Katana

Riconoscimenti