Aurelia e ASP.NET Core: lo scheletro del progetto

Questo post fa parte di una serie dedicata ad Aurelia e ASP.NET Core.

Avendo “chiacchierato” abbastanza nel primo post, è ora di mettere le mani su un po’ di codice. Io utilizzerò Visual Studio 2015 Enterprise (Update 3) ma non ho motivo di dubitare che sia possibile fare lo stesso sulla versione Community, su Visual Studio Code o anche utilizzando un qualsiasi editor testuale.

Nel momento in cui scrivo sto utilizzando i Microsoft .NET Core Tools (Preview 2) per Visual Studio.

Apriamo quindi Visual Studio e selezioniamo File > New > Project… e dalla categoria Visual C# > Web selezioniamo il template ASP.NET Core Web Application (.NET Core).

La consueta maschera di creazione del progetto consente di scegliere tra tre diversi template, che al solito aggiungono un po’ di codice di esempio al progetto vuoto. Non ho mai amato troppo queste aggiunte, non tanto perché riempiono il progetto di codice di dubbia utilità, quanto perché proponendo soluzioni preconfezionate fanno perdere di vista il funzionamento di quello che c’è “sotto il cofano”. Scegliamo quindi il template Empty e per ora ignoriamo la sezione relativa ad Azure su cui torneremo magari più avanti:

clip_image001

Dopo aver macinato un po’ l’hard disk, Visual Studio ci propone la struttura di base di una web application basata su ASP.NET Core (in realtà il risultato è leggermente diverso da quello dello screenshot seguente perché io preferisco prima creare una solution vuota, poi aggiungerci il project, spesso facendo anche un po’ di modifiche manuali alla struttura di base delle cartelle che non mi piace). Tanto per non farmi mancare nulla ho deciso di salvare il progetto su un repository Git che si trova sul mio account Visual Studio Team Services (VTST). Al momento non vedo implicazioni tra questo e la nostra “rotta”, quindi andremo avanti facendo finta che si tratti un progetto salvato in locale per poi magari tornare sull’argomento se ci sarà da pubblicare il sito su Azure sfruttando le funzioni di deploy e release management di VSTS:

clip_image002

Ci sono diverse differenze da notare in questa struttura rispetto a quella di un “vecchio” progetto ASP.NET ma non mi dilungherò ad analizzarle tutte in dettaglio visto che ci sono già svariati post su diversi blog che lo fanno egregiamente. Mi limiterò ad evidenziare brevemente quattro aspetti che a parer mio meritano la nostra attenzione.

Tutto è un pacchetto NuGet

Come accennato nel precedente post, ASP.NET Core è distribuito come federazione di pacchetti NuGet. Come conseguenza il nostro progetto non ha più dipendenze dirette con librerie del framework installate sulla nostra macchina, ma solo con quei pacchetti che implementano le funzionalità che ci servono.

Questo è immediatamente evidente aprendo il nodo References e confrontando un progetto basato sul .NET Framework completo con uno basato su .NET Core:

clip_image004

I pacchetti chiave di .NET Core sono i seguenti:

  • System.Runtime: è il nucleo di.NET Core e include ad esempio la definizione dei tipi Object, String, Array, Action e IList<T>;
  • System.Collections: contiene una serie di generic collections di base, come List<T> e Dictionary<K,V>;
  • System.Net.Http: include una serie di classi per le comunicazioni di rete via HTTP, tra cui HttpClient e HttpResponseMessage;
  • System.IO.FileSystem: è un insieme di classi per leggere e scrivere da storage locali o di rete, come File e Directory;
  • System.Linq: include una serie classi per interrogare oggetti, tra cui Enumerable e ILookup<TKey, TElement>;
  • System.Reflection: contiene le note classi per caricare, ispezionare e manipolare i tipi da codice a runtime, come Assembly, TypeInfo e MethodInfo.

È facile capire che il numero di pacchetti da cui un progetto mediamente può dipendere è cresciuto in modo esponenziale rispetto al vecchio approccio. Per fortuna è stata contemporaneamente migliora la gestione dei pacchetti ed è cambiata anche la modalità di visualizzazione sia sotto il nodo References che nella maschera di gestione dei pacchetti.

In un progetto .NET Core ci troveremo generalmente a non referenziare direttamente pacchetti di sistema, ma ad utilizzare invece dei metapackages. Questi ultimi sono pacchetti fittizi che non contengono alcuna funzionalità specifica (praticamente non hanno codice proprio) ma che servono solo per referenziare rapidamente una serie di altri pacchetti definiti come loro dipendenze.

In questo modo da un lato si semplifica l’acquisizione dei diversi pacchetti necessari per un comune progetto, d’altro ci si assicura che le varie versioni dei pacchetti siano tra loro coerenti.

Per il tipo di applicazione che abbiamo in mente, utilizzeremo il Microsoft.NETCore.App metapackage (attualmente alla versione 1.0.0) che include tutte le librerie che fanno parte della distribuzione di .NET Core e definisce inoltre il framework netcoreapp1.0. Approfondire quest’ultimo concetto esula dai miei scopi in questo momento, perché a parer mio non farebbe altro che aggiungere confusione. Se vi interessa potete consultare la documentazione ufficiale.

Come detto, e come si vede qui sopra, anche la modalità di visualizzazione è stata allineata a questo nuovo approccio e per default vengono riportati nella vista solo i pacchetti con dipendenza diretta, dai quali è sempre possibile navigare ad albero per scoprire le eventuali ulteriori dipendenze.

Dulcis in fundo, il nuovo file che contiene la lista dei pacchetti scaricati (il file project.json nella root di progetto) a differenza del precedente è manipolabile direttamente. È possibile digitare nella sezione dependencies il nome di un pacchetto che si vuole aggiungere (con tanto di intellisense) per ottenere lo stesso risultato del menu Manage NuGet Packages… e della Package Manager Console.

b6

Semplice come un file system

In un progetto.NET Core, il Solution Explorer mostra tutti i file presenti nella cartella del progetto: la “vecchia” lista di file inclusi nel progetto elencata nel file .csproj è stata finalmente abbandonata e questo rende molto più facile non solo aggiungere e rimuove file – è sufficiente copiare o cancellare un file nella cartella direttamente dal File Explorer di Windows – ma anche gestire il progetto su repository di codice sorgente quale ad esempio Team Foundation Server (TFS) o la sua controparte su cloud Visual Studio Team Service (VSTS).

clip_image005

Pubblicare solo il necessario

Ad una prima occhiata nel Solution Explorer, la cosa che più di altre salta agli occhi è la presenza di una cartella “particolare” chiamata wwwroot. Ricorda un po’ quella presente in IIS e rappresenta una svolta importante nella gestione delle applicazioni web con ASP.NET.

Fino ad oggi siamo stati abituati al fatto che tutto ciò che era presente nella cartella principale poteva di fatto essere servito al browser dal nostro server web. In un progetto MVC convivevano in maniera promiscua nella root del progetto sia elementi destinati direttamente al client – come ad esempio le immagini contenute nella cartella Images o i file JavaScript contenuti della cartella Scripts – che elementi inerenti il funzionamento lato server dell’applicazione – come i sorgenti presenti nelle cartelle Controllers, Models and Views o ancora il file di configurazione Web.config.

Questi ultimi erano progettati per essere processati all’interno del workflow di MVC ed emettere codice HTML e non per essere serviti direttamente al client (per intenderci con una richiesta HTTP verso la URL http://myapplication/Controllers/HomeController.cs ad esempio). Per evitare che ciò avvenisse, il motore di routing era dotato di una serie di regole che impedivano che certi file fossero raggiungibili direttamente dall’esterno con un meccanismo di blacklist.

In ASP.NET Core questo problema è stato risolto con un approccio radicalmente differente. Tutti, e soli, gli elementi presenti nella cartella wwwroot fanno parte di una whitelist che può essere servita al client direttamente (in altre parole come risorse statiche dotate di specifica URL). Se un file non si trova in wwwroot avete la sicurezza che non sarà possibile raggiungerlo e scaricarlo.

Non tutto è un pacchetto NuGet

L’altra novità rilevante nella lista presentata dal Solution Explorer è il nodo Dependencies che a prima vista sembra un duplicato di quello References di cui abbiamo già parlato, ma in realtà serve a distinguere le dipendenze lato server da quelle lato client, non tanto dal punto di vista logico ma soprattutto da quello dello strumento utilizzato per ottenerle.

Pare infatti che, mentre noi dormivamo beati tra i guanciali di ASP.NET, larga parte del mondo dello sviluppo web procedeva spedito in tutt’altra direzione, appoggiandosi a Node.js per sviluppare in JavaScript anche la parte server delle applicazioni. Anche in questo caso è inutile addentrarsi in un universo enorme e misterioso, sul quale tonnellate di materiale ben più qualificato di quello che potrei scrivere io è già disponibile.

Quello che ci interessa è che attorno a Node è fiorito un ecosistema di librerie e strumenti open source, facilmente accessibili tramite il suo package manager dedicato, NPM. Per chi viene da ASP.NET e sente parlare di NPM per la prima volta, il paragone più immediato è con NuGet. Se fino a ieri eravamo abituati ad usare NuGet per ottenere tanto una libreria .NET da usare nel codice lato server (come ad esempio Json.NET) quanto una JavaScript da usare nelle pagine lato client (vedi jQuery), da oggi Microsoft ha finalmente deciso di essere stanca di reinventare la ruota. NuGet rimane vivo e vegeto per il primo tipo di librerie, mentre per tutto ciò che attiene al client ASP.NET Core e Visual Studio fanno riferimento a NPM, cioè come detto al package manager di Node, in definitiva il più grande contenitore di librerie open source al mondo.

A riprova, se proviamo a cercare jQuery dal Manage NuGet Packages… otteniamo un avvertimento che ci invita ad usare Bower invece che NuGet (ad oggi è solo un avvertimento, non un divieto):

clip_image006

Come Bower? Ma non abbiamo appena detto che saremmo passati da NuGet a NPM? Sì e no; il mondo open source è pieno di sorprese e poi un solo package manager non sarebbe abbastanza nerd.

Ne sapremo di più al prossimo post.

Happy coding!

 

P.S. Il codice sorgente è disponibile su GitHub, basta scaricare la release con lo stesso nome del post (Lo scheletro del progetto in questo caso).

«ottobre»
domlunmarmergiovensab
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345