Sviluppare app ASP.NET Core usando un watcher per file
Di Rick Anderson e Victor Hurdugaci
dotnet watch
è uno strumento che esegue un comando dell'interfaccia della riga di comando di .NET quando i file di origine cambiano. Ad esempio, una modifica di file può attivare la compilazione, l'esecuzione di test o la distribuzione.
Questa esercitazione usa un'API Web esistente con due endpoint, di cui uno restituisce una somma e l'altro un prodotto. Il metodo del prodotto ha un bug, che verrà corretto in questa esercitazione.
Scaricare l'app di esempio. Questa è costituita da due progetti: WebApp (un'API Web di ASP.NET Core) e WebAppTests (unit test per l'API Web).
In una shell dei comandi passare alla cartella WebApp. Eseguire il comando riportato di seguito:
dotnet run
Nota
È possibile usare dotnet run --project <PROJECT>
per specificare un progetto da eseguire. Ad esempio, l'esecuzione di dotnet run --project WebApp
dalla radice dell'app di esempio consentirà di eseguire anche il progetto WebApp.
L'output della console visualizza messaggi simili al seguente che indicano che l'app è in esecuzione e in attesa di richieste:
$ dotnet run
Hosting environment: Development
Content root path: C:/Docs/aspnetcore/tutorials/dotnet-watch/sample/WebApp
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
In un Web browser accedere a http://localhost:<port number>/api/math/sum?a=4&b=5
. Dovrebbe essere visualizzato il risultato 9
.
Passare all'API del prodotto (http://localhost:<port number>/api/math/product?a=4&b=5
). Restituisce 9
e non 20
come previsto. Questo problema verrà corretto più avanti nell'esercitazione.
Aggiungere dotnet watch
a un progetto
Lo strumento watcher per file dotnet watch
è incluso nella versione 2.1.300 di .NET Core SDK. Se si usa una versione precedente di .NET Core SDK, i passaggi seguenti sono obbligatori.
Aggiungere un
Microsoft.DotNet.Watcher.Tools
riferimento al pacchetto al.csproj
file:<ItemGroup> <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" /> </ItemGroup>
Installare il pacchetto
Microsoft.DotNet.Watcher.Tools
eseguendo il comando seguente:dotnet restore
Eseguire i comandi dell'interfaccia della riga di comando di .NET usando dotnet watch
Qualsiasi comando dell'interfaccia della riga di comando di .NET può essere eseguito con dotnet watch
. Ad esempio:
Comando | Comando con watch |
---|---|
dotnet run | dotnet watch run |
dotnet run -f netcoreapp3.1 | dotnet watch run -f netcoreapp3.1 |
dotnet run -f netcoreapp3.1 -- --arg1 | dotnet watch run -f netcoreapp3.1 -- --arg1 |
dotnet test | dotnet watch test |
Eseguire dotnet watch run
nella cartella WebApp. L'output della console indica che watch
è stato avviato.
L'esecuzione dotnet watch run
in un'app Web avvia un browser che passa all'URL dell'app una volta pronto. dotnet watch
a tale scopo, leggere l'output della console dell'app e attendere il messaggio pronto visualizzato da WebHost.
dotnet watch
aggiorna il browser quando rileva le modifiche apportate ai file visualizzati. A tale scopo, il comando watch inserisce un middleware nell'app che modifica le risposte HTML create dall'app. Il middleware aggiunge un blocco di script JavaScript alla pagina che consente dotnet watch
di indicare al browser di eseguire l'aggiornamento. Attualmente, le modifiche a tutti i file visualizzati, incluso il contenuto statico, ad .html
esempio e .css
i file, causano la ricompilazione dell'app.
dotnet watch
:
- Controlla solo i file che influisce sulle compilazioni per impostazione predefinita.
- Tutti i file di controllo aggiuntivi (tramite configurazione) continuano a verificarsi una compilazione.
Per altre informazioni sulla configurazione, vedere configurazione dotnet-watch in questo documento.
Nota
È possibile usare dotnet watch --project <PROJECT>
per specificare un progetto da controllare. Ad esempio, l'esecuzione di dotnet watch --project WebApp run
dalla radice dell'app di esempio consentirà di eseguire e controllare anche il progetto WebApp.
Apportare modifiche con dotnet watch
Assicurarsi che dotnet watch
sia in esecuzione.
Correggere il bug nel Product
metodo di MathController.cs
in modo che restituisca il prodotto e non la somma:
public static int Product(int a, int b)
{
return a * b;
}
Salvare il file. L'output della console indica che dotnet watch
ha rilevato una modifica del file e ha riavviato l'app.
Verificare che http://localhost:<port number>/api/math/product?a=4&b=5
restituisca il risultato corretto.
Eseguire test con dotnet watch
Modificare il
Product
metodo diMathController.cs
tornare a restituire la somma. Salvare il file.In una shell dei comandi passare alla cartella WebAppTests.
Eseguire dotnet restore.
Eseguire
dotnet watch test
. L'output indica che un test non è stato superato e che il watcher è in attesa di modifiche ai file:Total tests: 2. Passed: 1. Failed: 1. Skipped: 0. Test Run Failed.
Correggere il codice del metodo
Product
in modo che restituisca il prodotto. Salvare il file.
dotnet watch
rileva la modifica ai file ed esegue di nuovo i test. L'output della console indica che i test sono stati superati.
Personalizzare l'elenco dei file da controllare
Per impostazione predefinita, dotnet-watch
tiene traccia di tutti i file che soddisfano i criteri GLOB seguenti:
**/*.cs
*.csproj
**/*.resx
- File di contenuto:
wwwroot/**
,**/*.config
,**/*.json
È possibile aggiungere altri elementi all'elenco espressioni di controllo modificando il .csproj
file. Gli elementi possono essere specificati singolarmente o tramite criteri GLOB.
<ItemGroup>
<!-- extends watching group to include *.js files -->
<Watch Include="**\*.js" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" />
</ItemGroup>
Esclusione di file dal controllo
È possibile configurare dotnet-watch
in modo che ignori le impostazioni predefinite. Per ignorare file specifici, aggiungere l'attributo Watch="false"
alla definizione di un elemento nel .csproj
file:
<ItemGroup>
<!-- exclude Generated.cs from dotnet-watch -->
<Compile Include="Generated.cs" Watch="false" />
<!-- exclude Strings.resx from dotnet-watch -->
<EmbeddedResource Include="Strings.resx" Watch="false" />
<!-- exclude changes in this referenced project -->
<ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" Watch="false" />
</ItemGroup>
<ItemGroup>
<!-- Exclude all Content items from being watched. -->
<Content Update="@(Content)" Watch="false" />
</ItemGroup>
Progetti di controllo personalizzati
dotnet-watch
non è limitato a progetti C#. È possibile creare progetti di controllo personalizzati per gestire scenari diversi. Si consideri il layout di progetto seguente:
- test/
UnitTests/UnitTests.csproj
IntegrationTests/IntegrationTests.csproj
Se l'obiettivo consiste nel controllare entrambi i progetti, creare un file di progetto personalizzato configurato per controllarli entrambi:
<Project>
<ItemGroup>
<TestProjects Include="**\*.csproj" />
<Watch Include="**\*.cs" />
</ItemGroup>
<Target Name="Test">
<MSBuild Targets="VSTest" Projects="@(TestProjects)" />
</Target>
<Import Project="$(MSBuildExtensionsPath)\Microsoft.Common.targets" />
</Project>
Per avviare il controllo dei file per entrambi i progetti, passare alla cartella test. Eseguire il comando seguente:
dotnet watch msbuild /t:Test
VSTest viene eseguito quando un qualsiasi file viene modificato in uno dei progetti di test.
Configurazione dotnet-watch
Alcune opzioni di configurazione possono essere passate tramite variabili di dotnet watch
ambiente. Le variabili disponibili sono:
Impostazione | Descrizione |
---|---|
DOTNET_USE_POLLING_FILE_WATCHER |
Se impostato su "1" o "true", dotnet watch usa un watcher del file di polling anziché corefx.FileSystemWatcher Usato quando si osservano i file nelle condivisioni di rete o nei volumi montati da Docker. |
DOTNET_WATCH_SUPPRESS_MSBUILD_INCREMENTALISM |
Per impostazione predefinita, dotnet watch ottimizza la compilazione evitando determinate operazioni, ad esempio l'esecuzione del ripristino o la rivalutazione del set di file watched in ogni modifica del file. Se impostato su "1" o "true", queste ottimizzazioni sono disabilitate. |
DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER |
dotnet watch run tenta di avviare browser per le app Web con launchBrowser configurate in launchSettings.json . Se impostato su "1" o "true", questo comportamento viene eliminato. |
DOTNET_WATCH_SUPPRESS_BROWSER_REFRESH |
dotnet watch run tenta di aggiornare i browser quando rileva le modifiche apportate ai file. Se impostato su "1" o "true", questo comportamento viene eliminato. Questo comportamento viene eliminato anche se DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER è impostato. |
Aggiornamento del browser
dotnet watch
inserisce uno script nell'app che consente di aggiornare il browser quando cambia il contenuto. In alcuni scenari, ad esempio quando l'app abilita la compressione delle risposte, dotnet watch
potrebbe non essere in grado di inserire lo script. Per questi casi in fase di sviluppo, inserire manualmente lo script nell'app. Ad esempio, per configurare l'app Web per inserire manualmente lo script, aggiornare il file di layout in modo da includere _framework/aspnet-browser-refresh.js
:
@* _Layout.cshtml *@
<environment names="Development">
<script src="/_framework/aspnetcore-browser-refresh.js"></script>
</environment>
Caratteri non ASCII
Visual Studio 17.2 e versioni successive include .NET SDK 6.0.300 e versioni successive. Con .NET SDK e 6.0.300 versioni successive, dotnet-watch
genera caratteri non ASCII nella console durante una sessione di ricaricamento rapido. In alcuni host della console, ad esempio il conhost di Windows, questi caratteri potrebbero apparire incomprensibili. Per evitare caratteri incomprensibili, considerare uno degli approcci seguenti:
- Configurare la variabile di ambiente per eliminare l'emissione
DOTNET_WATCH_SUPPRESS_EMOJIS=1
di questi valori. - Passare a un terminale diverso, ad esempio https://github.com/microsoft/terminal, che supporta il rendering di caratteri non ASCII.