Panoramica di Project Katana

di Howard Dierking

Il framework ASP.NET è stato intorno da oltre dieci anni e la piattaforma ha abilitato lo sviluppo di innumerevoli siti Web e servizi. Con l'evoluzione delle strategie di sviluppo di applicazioni Web, il framework è stato in grado di evolversi di pari passo con tecnologie come ASP.NET MVC e ASP.NET Web API. Man mano che lo sviluppo di applicazioni Web porta avanti 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 offrire prestazioni migliori. Il progetto Katana cloud ottimizza le applicazioni ASP.NET.

Perché Katana – Perché adesso?

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 dinamici e basati sui dati e applicazioni tramite markup e script sul lato server. Il runtime ASP ha fornito uno script sul lato server con un set di oggetti che astraggono 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 sessione, la cache e così via. Anche se le applicazioni ASP classiche sono diventate una sfida da gestire man mano che sono cresciute di dimensioni e complessità. Ciò è dovuto in gran parte alla mancanza di struttura trovata negli ambienti di scripting, insieme alla duplicazione del codice risultante dall'interleaving del codice e del markup. Per sfruttare al tempo stesso i punti di forza di ASP classico e affrontare alcune delle sue sfide, ASP.NET ha sfruttato l'organizzazione del codice fornita dai linguaggi orientati agli oggetti di .NET Framework, mantenendo al tempo stesso il modello di programmazione lato server a cui gli sviluppatori ASP classici erano abituati.

Il secondo gruppo di clienti di destinazione per ASP.NET era sviluppatore di applicazioni aziendali di Windows. A differenza degli sviluppatori ASP classici, che erano 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 Form", ha fornito 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 ottimale tra la programmazione lato client e server. I Web Form nascondevano 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 runtime maturo e ricco di funzionalità con un modello di programmazione per sviluppatori. Tuttavia, con quella ricchezza di funzionalità sono emerse alcune 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 significa che il tempo tra le versioni era nell'ordine di anni. Ciò ha reso difficile per ASP.NET tenere il passo con tutti i cambiamenti che si verificano nello sviluppo Web in rapida evoluzione. Infine, System.Web.dll è stato accoppiato in vari modi a 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 è stato aumentato a una velocità sempre più veloce. È stato chiaro che mantenere il passo con il Web richiederebbe che i framework siano più piccoli, disaccoppiati e più concentrati piuttosto che più grandi e più ricchi di funzionalità, pertanto 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 compilazione 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, che era 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 dell'architettura ha contribuito a spingere l'aumento delle API Web e allo sviluppo del framework API Web ASP.NET. Come nel caso di ASP.NET MVC, il rilascio di ASP.NET API Web ha offerto un'altra opportunità per evolvere ulteriormente ASP.NET come framework più modulare. Il team di progettazione ha sfruttato l'opportunità e creato ASP.NET'API Web in modo che non avesse dipendenze da nessuno dei tipi di framework di base trovati in System.Web.dll. Questo ha abilitato due cose: per prima cosa, significa che ASP.NET API Web può evolversi in modo completamente autonomo (e potrebbe continuare a scorrere rapidamente perché viene distribuito tramite NuGet). In secondo luogo, poiché non c'erano dipendenze esterne per System.Web.dlle pertanto nessuna dipendenza da IIS, ASP.NET'API Web includeva la funzionalità di esecuzione in un host personalizzato (ad esempio, un'applicazione console, un servizio Windows e così via).

Il futuro: un framework agile

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

Ciò che era necessario era un'unica astrazione di hosting che consentiva a uno sviluppatore di comporre un'applicazione da diversi componenti e framework e quindi eseguirla in un host di supporto.

Interfaccia Web Aperta per .NET (OWIN)

Ispirato ai vantaggi ottenuti da Rack nella community Ruby, diversi membri della community .NET hanno stabilito di 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 richiesto il minor numero possibile di dipendenze da altri tipi di framework. Questi due obiettivi contribuiscono a garantire:

  • I nuovi componenti potrebbero essere più facilmente sviluppati e utilizzati.
  • Le applicazioni potrebbero essere più facilmente convertite 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 di contenuto e le raccolte di intestazioni per una richiesta e una risposta HTTP. È quindi responsabilità dei componenti dell'applicazione o 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 principale. Ad esempio, la tabella seguente mostra le chiavi del dizionario necessarie per una richiesta HTTP:

Nome chiave Descrizione del valore
"owin.RequestBody" Un flusso dati 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" Una collezione IDictionary<string, string[]> di intestazioni di richiesta. Consultare Intestazioni.
"owin.RequestMethod" Oggetto string contenente il metodo di richiesta HTTP della richiesta , ad esempio "GET", "POST".
"owin.RequestPath" Un 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" Un oggetto string che contiene il componente della stringa di query dell'URI della richiesta HTTP, senza il "?" 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 è quindi 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 in operazioni più complesse di I/O.
  • Poiché il delegato dell'applicazione è un'unità atomica di esecuzione e poiché il dizionario dell'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. Sebbene non sia 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.

Progetto Katana

Mentre sia la specifica OWIN che Owin.dll sono di proprietà della community eseguono attività open source, il progetto Katana rappresenta il set di componenti OWIN che, pur rimanendo open source, vengono compilati e rilasciati da Microsoft. Questi componenti includono componenti dell'infrastruttura, ad esempio host e server, nonché 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 con i nuovi componenti man mano che 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 senza problemi nei server Microsoft, mentre i framework Microsoft possono 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 mirati, dando il controllo allo sviluppatore dell'applicazione per determinare quali componenti usare nell'applicazione.
  • Leggero/efficiente/scalabile : suddividendo la nozione tradizionale di un framework in un set di componenti piccoli e incentrati 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, è possibile aggiungerle alla pipeline OWIN, ma questo deve essere una decisione esplicita da parte dello sviluppatore di applicazioni. Inoltre, la sostituzione dei componenti di livello inferiore significa che, man mano che diventano disponibili, è possibile introdurre facilmente nuovi server ad alte prestazioni per migliorare le prestazioni delle applicazioni OWIN senza interrompere tali applicazioni.

Introduzione ai componenti katana

Quando è stato introdotto per la prima volta, un aspetto del framework Node.js che immediatamente attirava l'attenzione delle persone era la semplicità con cui si poteva creare ed eseguire un server Web. Se gli obiettivi di Katana fossero considerati nella prospettiva di Node.js, si potrebbe riepilogarli dicendo che Katana offre molti dei vantaggi di Node.js (e framework come questi) senza costringere lo sviluppatore ad abbandonare tutto ciò che sa sullo sviluppo di applicazioni Web ASP.NET. Affinché questa dichiarazione sia vera, iniziare a usare il progetto Katana deve essere altrettanto semplice quanto Node.js.

Creazione di "Hello World!"

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

Screenshot del progetto ASP.Net - WebApplication1 che illustra come utilizzare il pannello 'Get Started' per creare un progetto 'Hello World'. Mostra una finestra con diversi template da selezionare e le opzioni per aggiungere riferimenti di base e test unitari.

Verrà quindi installato il pacchetto NuGet Microsoft.Owin.Host.SystemWeb nel progetto. Questo pacchetto fornisce un server OWIN eseguito nella pipeline di richiesta ASP.NET. È disponibile 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 di supporto e metodi 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.

Cambio 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. Questo può da solo aggiungere enorme valore perché ci 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, possono verificarsi casi in cui i vantaggi offerti da IIS non sono necessari e il desiderio è per un host più piccolo e leggero. Cosa è necessario per eseguire il server Web semplice all'esterno di IIS e System.Web?

Per illustrare l'obiettivo di portabilità, il passaggio 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 l'avvio dell'host. In questo esempio il server Web verrà ospitato in un host Katana denominato OwinHost.exe e verrà usato 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 installato 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. Navigare in un browser Web su http://localhost:5000/ per mostrare che l'applicazione è ora in esecuzione tramite la console.

Screenshot della finestra Developer Command Promt e del browser, che mostra un confronto tra i comandi immessi nella riga di comando e l'aspetto del progetto 'Hello World' nel Web browser.

Architettura katana

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

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

Host

L'host è responsabile di:

  • Gestione del processo sottostante.

  • Orchestrazione del flusso di lavoro che determina 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 principali 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. Il supporto di hosting ASP.NET è abilitato dall'installazione del pacchetto NuGet Microsoft.AspNet.Host.SystemWeb in un progetto di applicazione Web. Inoltre, poiché IIS funge sia da host che da server, la distinzione tra server o host OWIN viene gonfiata 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 si tratti di un'applicazione console, di un servizio Windows e così via. Questa funzionalità è simile alla funzionalità self-host fornita dall'API Web. L'esempio seguente mostra 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 alla seguente:

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 significativa tra l'API Web e gli esempi di self-host Katana è che il codice di configurazione dell'API Web non è presente nell'esempio di self-host Katana. Per abilitare sia la portabilità che 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 specificata anche 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 "startup class" verrà illustrata in modo più dettagliato più avanti nell'articolo. Tuttavia, il codice necessario per avviare un processo self-host Katana sembra sorprendentemente simile al codice attualmente in uso nelle applicazioni self-host dell'API Web ASP.NET.

OwinHost.exe: mentre alcuni vogliono scrivere un processo personalizzato per eseguire applicazioni Web Katana, molti preferiscono semplicemente avviare un eseguibile predefinito che possa 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à le convenzioni per trovare ed eseguire la classe di avvio dell'utente. Per un controllo più granulare, l'eseguibile fornisce una serie di parametri aggiuntivi della riga di comando.

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

Servidor

Mentre l'host è responsabile dell'avvio e della gestione del processo in cui viene eseguita l'applicazione, la responsabilità del server è aprire un socket di rete, ascoltare le richieste e inviarle tramite la pipeline di 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 accennato in precedenza, IIS insieme alla pipeline 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 rimane in 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 attraverso 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 a una pipeline OWIN specificata dallo sviluppatore. Questa è attualmente la selezione del server predefinita per l'API self-host Katana e OwinHost.exe.

Middleware/framework (software di interconnessione/quadro di riferimento)

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 un 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 serie di convenzioni e tipi helper per i componenti middleware. La più comune di queste è la OwinMiddleware classe . Un componente middleware personalizzato compilato con 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 Invoke sovrascritto. Questo metodo accetta un singolo argomento di tipo OwinContext. Questo oggetto di contesto viene fornito dal Microsoft.Owin pacchetto NuGet descritto in precedenza e fornisce l'accesso fortemente tipizzato alla richiesta, alla risposta e al dizionario dell'ambiente, oltre ad alcuni tipi di helper aggiuntivi.

La classe middleware può essere aggiunta facilmente 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 poiché i componenti devono semplicemente supportare il delegato dell'applicazione per partecipare alla pipeline, i componenti middleware possono variare in complessità da semplici logger a interi framework come ASP.NET, API Web o SignalR. Ad esempio, l'aggiunta di ASP.NET API Web 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 dalla modalità di gestione di tali richieste. 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 ASP.NET API Web, SignalR e un file server statico.

Applicazioni

Come illustrato negli esempi precedenti, OWIN e il progetto Katana non devono essere considerati come un nuovo modello di programmazione delle applicazioni, ma piuttosto come astrazione per separare modelli di programmazione e framework di programmazione delle applicazioni dall'infrastruttura server e hosting. Ad esempio, quando si compilano applicazioni API Web, il framework di sviluppo continuerà a usare il framework 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 di moduli HTTP nel mondo System.Web corrente. In genere, un middleware del framework più ampio, ad esempio ASP.NET API Web o SignalR verrà registrato alla fine della pipeline. I componenti middleware trasversali, ad esempio quelli per l'autenticazione o la memorizzazione nella cache, vengono in genere 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 l'uno dall'altro e dai componenti dell'infrastruttura sottostanti consente ai componenti di evolversi a velocità diverse, garantendo al tempo stesso che il sistema complessivo rimanga stabile.

Componenti : pacchetti NuGet

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

Diagramma della gerarchia dei componenti - 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 pacchetti di infrastruttura di hosting (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.exee il pacchetto Microsoft.Owin.Hosting per applicazioni OWIN self-hosting in un host personalizzato (ad esempio, applicazione console, servizio Windows e così via)

Per Katana 2.0, i componenti middleware sono principalmente incentrati sulla fornitura di diversi mezzi di autenticazione. Viene fornito un componente middleware aggiuntivo per la diagnostica, che consente il supporto per una pagina di avvio e di errore. Man mano che OWIN cresce nell'astrazione host de facto, l'ecosistema di componenti middleware, sia quelli sviluppati da Microsoft che da terze parti, crescerà anche in numero.

Conclusione

Fin dall'inizio, l'obiettivo del progetto Katana non è stato quello di creare e costringere 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 gli strati logici di un tipico applicativo Web in un set di componenti sostituibili, il progetto Katana consente il miglioramento dei componenti sull'intero stack a qualsiasi velocità abbia senso per tali componenti. Creando tutti i componenti intorno alla semplice astrazione OWIN, Katana consente ai framework e alle applicazioni basate su di essi di essere portabili in un'ampia gamma di server e host diversi. Mettendo lo sviluppatore al controllo dello stack, Katana garantisce che lo sviluppatore faccia la scelta finale su quanto sia leggero o ricco di funzionalità il suo stack Web.

Per altre informazioni su Katana

Ringraziamenti