Condividi tramite


Sviluppare app ASP.NET Core usando un watcher di 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 del file può attivare la compilazione, l'esecuzione di test o la distribuzione.

Questa esercitazione usa un'API Web esistente con due endpoint: uno che restituisce una somma e una che restituisce un prodotto. Il metodo del prodotto presenta un bug che viene risolto in questo tutorial.

Scaricare l'app di esempio . È costituito da due progetti: WebApp (un'API Web ASP.NET Core) e WebAppTests (unit test per l'API Web).

Passare alla cartella WebApp nella shell dei comandi. Eseguire il comando seguente:

dotnet run

Note

È possibile usare dotnet run --project <PROJECT> per specificare un progetto da eseguire. Ad esempio, l'esecuzione dotnet run --project WebApp dalla radice dell'app di esempio eseguirà anche il progetto App Web .

L'output della console mostra messaggi simili al seguente (a indicare 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. Verrà visualizzato il risultato di 9.

Passare all'API del prodotto (http://localhost:<port number>/api/math/product?a=4&b=5). Restituisce 9, non 20 come previsto. Questo problema è stato risolto più avanti nell'esercitazione.

Aggiungere dotnet watch a un progetto

Lo dotnet watch strumento file watcher è incluso nella versione 2.1.300 di .NET SDK. Quando si usa una versione precedente di .NET SDK, sono necessari i passaggi seguenti.

  1. Aggiungere un riferimento al pacchetto Microsoft.DotNet.Watcher.Tools al file .csproj:

    <ItemGroup>
        <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
    </ItemGroup>
    
  2. 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. For example:

Command Comando con monitoraggio
dotnet run dotnet watch run (esegui e monitora usando dotnet)
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 test dotnet watch

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 monitorati, inclusi i contenuti statici come i file .html e .css, causano la ricompilazione dell'app.

dotnet watch:

  • Controlla solo i file che influiscono sui processi di compilazione per impostazione predefinita.
  • Qualsiasi file monitorato aggiuntivo (tramite configurazione) farà sì che venga eseguita una compilazione.

Per altre informazioni sulla configurazione, vedere configurazione dotnet-watch in questo documento.

Note

È possibile usare dotnet watch --project <PROJECT> per specificare un progetto da controllare. Ad esempio, eseguendo dotnet watch --project WebApp run dalla directory principale dell'app di esempio, verrà eseguito e verrà monitorato 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;
}

Salva il file. L'output della console indica che dotnet watch è stata rilevata una modifica del file e che l'app è stata riavviata.

Verifica che http://localhost:<port number>/api/math/product?a=4&b=5 restituisca il risultato corretto.

Eseguire test con dotnet watch

  1. Modifica il metodo Product di MathController.cs per tornare a restituire la somma. Salva il file.

  2. Nel terminale dei comandi, vai alla cartella WebAppTests.

  3. Eseguire dotnet restore.

  4. Esegui dotnet watch test. L'output indica che un test non è riuscito e che il watcher è in attesa di modifiche al file:

    Total tests: 2. Passed: 1. Failed: 1. Skipped: 0.
    Test Run Failed.
    
  5. Correggere il codice del Product metodo in modo che restituisca il prodotto. Salva il file.

dotnet watch rileva la modifica del file ed esegue nuovamente i test. L'output della console indica i test superati.

Personalizzare l'elenco di file da controllare

Per impostazione predefinita, dotnet-watch tiene traccia di tutti i file corrispondenti ai modelli GLOB seguenti:

  • **/*.cs
  • *.csproj
  • **/*.resx
  • File di contenuto: wwwroot/**, **/*.config, **/*.json

Possono essere aggiunti altri elementi alla lista di monitoraggio modificando il file .csproj. Gli elementi possono essere specificati singolarmente o usando modelli glob.

<ItemGroup>
    <!-- extends watching group to include *.js files -->
    <Watch Include="**\*.js" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" />
</ItemGroup>

Rifiutare esplicitamente i file da controllare

dotnet-watch può essere configurato per ignorare 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 orologi su misura

dotnet-watch non è limitato ai 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 è controllare entrambi i progetti, creare un file di progetto personalizzato configurato per controllare entrambi i progetti:

<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 in entrambi i progetti, passare alla cartella di test . Eseguire il comando seguente:

dotnet watch msbuild /t:Test

VSTest viene eseguito quando un file cambia in uno dei progetti di test.

dotnet-watch configuration

Alcune opzioni di configurazione possono essere passate a dotnet watch tramite variabili di ambiente. Le variabili disponibili sono:

Setting Description
DOTNET_USE_POLLING_FILE_WATCHER Se impostato su "1" o "true", dotnet watch usa un osservatore di file per il 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 costruzione evitando determinate operazioni, come l'esecuzione del ripristino o la rivalutazione del set di file monitorati ad 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 i browser per le applicazioni web con launchBrowser configurato/a 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.

Browser refresh

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>

Non-ASCII characters

Visual Studio 17.2 o versione successiva include il .NET SDK 6.0.300 o versione successiva. 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.