diff --git a/aspnetcore/tutorials/dotnet-watch.md b/aspnetcore/tutorials/dotnet-watch.md index b85ad9f4cd..c8d89f2f37 100644 --- a/aspnetcore/tutorials/dotnet-watch.md +++ b/aspnetcore/tutorials/dotnet-watch.md @@ -1,195 +1,97 @@ --- -title: Developing ASP.NET Core applications using dotnet watch | Microsoft Docs +title: Developing ASP.NET Core apps using dotnet watch | Microsoft Docs author: rick-anderson -description: -keywords: ASP.NET Core, +description: Shows how to use dotnet watch. +keywords: ASP.NET Core, using dotnet watch ms.author: riande manager: wpickett -ms.date: 10/14/2016 +ms.date: 02/14/2017 ms.topic: article ms.assetid: 563ffb3f-d369-4aa5-bf0a-7300b4e7832c ms.technology: aspnet ms.prod: asp.net-core uid: tutorials/dotnet-watch --- -# Developing ASP.NET Core applications using dotnet watch +# Developing ASP.NET Core apps using dotnet watch - -By [Victor Hurdugaci](https://twitter.com/victorhurdugaci) +By [Rick Anderson](https://twitter.com/RickAndMSFT) and [Victor Hurdugaci](https://twitter.com/victorhurdugaci) -## Introduction +`dotnet watch` is a tool that runs a `dotnet` command when source files change. For example, a file change can trigger compilation, tests, or deployment. -`dotnet watch` is a development time tool that runs a `dotnet` command when source files change. It can be used to compile, run tests, or publish when code changes. +In this tutorial we use an existing Web API app with two endpoints: one that returns a sum and one that returns a product. The product method contains an bug that we'll fix as part of this tutorial. -In this tutorial we'll use an existing WebApi application that calculates the sum and product of two numbers to demonstrate the use cases of `dotnet watch`. The sample application contains an intentional bug that we'll fix as part of this tutorial. +Download the [sample app](https://github.com/aspnet/Docs/tree/master/aspnetcore/tutorials/dotnet-watch/sample). It contains two projects, `WebApp` (a web app) and `WebAppTests` (unit tests for the web app). -## Getting started +In a console, navigate to the WebApp folder and run the following commands: -Start by downloading [the sample application](https://github.com/aspnet/Docs/tree/master/aspnetcore/tutorials/dotnet-watch/sample). It contains two projects, `WebApp` (a web application) and `WebAppTests` (unit tests for the web application) +- `dotnet restore` +- `dotnet run` -In a console, open the folder where you downloaded the sample application and run: +The console output will show messages similar to the following (indicating that the app is running and waiting for requests): -1. `dotnet restore` -2. `cd WebApp` -3. `dotnet run` - -The console output will show messages similar to the ones below, indicating that the application is now running and waiting for requests: - -```bash +```console $ dotnet run -Project WebApp (.NETCoreApp,Version=v1.0) will be compiled because inputs were modified -Compiling WebApp for .NETCoreApp,Version=v1.0 - -Compilation succeeded. - 0 Warning(s) - 0 Error(s) - -Time elapsed 00:00:02.6049991 - Hosting environment: Production -Content root path: /Users/user/dev/aspnet/Docs/aspnet/tutorials/dotnet-watch/sample/WebApp +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 a web browser, navigate to `http://localhost:5000/api/math/sum?a=4&b=5` and you should see the result `9`. +In a web browser, navigate to `http://localhost:5000/api/math/sum?a=4&b=5`, you should see the result `9`. -If you navigate to `http://localhost:5000/api/math/product?a=4&b=5` instead, you'd expect to get the result `20`. Instead, you get `9` again. +Navigate to the product API (`http://localhost:5000/api/math/product?a=4&b=5`), it returns `9`, not `20` as you'd expect. We'll fix that later in the tutorial. -We'll fix that. +## Add `dotnet watch` to a project -## Adding `dotnet watch` to a project +- Add `Microsoft.DotNet.Watcher.Tools` to the *.csproj* file: + ```xml + + + ``` -1. Add `Microsoft.DotNet.Watcher.Tools` to the `tools` section of the *WebApp/project.json* file. -2. Run `dotnet restore`. - -The console output will show messages similar to the ones below: - -```bash -log : Restoring packages for /Users/user/dev/aspnet/Docs/aspnet/tutorials/dotnet-watch/sample/WebApp/project.json... -log : Restoring packages for tool 'Microsoft.DotNet.Watcher.Tools' in /Users/user/dev/aspnet/Docs/aspnet/tutorials/dotnet-watch/sample/WebApp/project.json... -log : Installing Microsoft.DotNet.Watcher.Core ... -log : Installing Microsoft.DotNet.Watcher.Tools ... -``` +- Run `dotnet restore`. ## Running `dotnet` commands using `dotnet watch` -Any `dotnet` command can be run with `dotnet watch`: For example: - - +Any `dotnet` command can be run with `dotnet watch`, for example: | Command | Command with watch | | ---- | ----- | -| dotnet run | dotnet watch run | +| dotnet run | dotnet watch run | | dotnet run -f net451 | dotnet watch run -f net451 | | dotnet run -f net451 -- --arg1 | dotnet watch run -f net451 -- --arg1 | | dotnet test | dotnet watch test | -To run `WebApp` using the watcher, run `dotnet watch run` in the `WebApp` folder. The console output will show messages similar to the ones below, indicating that `dotnet watch` is now watching code files: - -```bash -user$ dotnet watch run -[DotNetWatcher] info: Running dotnet with the following arguments: run -[DotNetWatcher] info: dotnet process id: 39746 -Project WebApp (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation. -Hosting environment: Production -Content root path: /Users/user/dev/aspnet/Docs/aspnet/tutorials/dotnet-watch/sample/WebApp -Now listening on: http://localhost:5000 -Application started. Press Ctrl+C to shut down. -``` +Run `dotnet watch run` in the `WebApp` folder. The console output will indicate `watch` has started. ## Making changes with `dotnet watch` Make sure `dotnet watch` is running. -Let's fix the bug in *WebApp/Controllers/MathController.cs* that we discovered when we tried to compute the product of two number: +Fix the bug in the `Product` method of the `MathController` so it returns the product and not the sum. -[!code-csharp[Main](dotnet-watch/sample/WebApp/Controllers/MathController.cs?range=12-17&highlight=5)] +```csharp +public static int Product(int a, int b) +{ + return a * b; +} ``` -Fix the code by replacing `a + b` with `a * b`. - -Save the file. The console output will show messages similar to the ones below, indicating that `dotnet watch` detected a file change and restarted the application. - -```bash -[DotNetWatcher] info: File changed: /Users/user/dev/aspnet/Docs/aspnet/tutorials/dotnet-watch/sample/WebApp/Controllers/MathController.cs -[DotNetWatcher] info: Running dotnet with the following arguments: run -[DotNetWatcher] info: dotnet process id: 39940 -Project WebApp (.NETCoreApp,Version=v1.0) will be compiled because inputs were modified -Compiling WebApp for .NETCoreApp,Version=v1.0 -Compilation succeeded. - 0 Warning(s) - 0 Error(s) -Time elapsed 00:00:03.3312829 - -Hosting environment: Production -Content root path: /Users/user/dev/aspnet/Docs/aspnet/tutorials/dotnet-watch/sample/WebApp -Now listening on: http://localhost:5000 -Application started. Press Ctrl+C to shut down. -``` +Save the file. The console output will show messages indicating that `dotnet watch` detected a file change and restarted the app. Verify `http://localhost:5000/api/math/product?a=4&b=5` returns the correct result. ## Running tests using `dotnet watch` -The file watcher can run other `dotnet` commands like `test` or `publish`. +- Change the `Product` method of the `MathController` back to returning the sum and save the file. +- In a command window, naviagate to the `WebAppTests` folder. +- Run `dotnet restore` +- Run `dotnet watch test`. You see output indicating that a test failed and that watcher is waiting for file changes: -1. Open the `WebAppTests` folder that already has `dotnet watch` in *project.json*. + ```console + Total tests: 2. Passed: 1. Failed: 1. Skipped: 0. + Test Run Failed. + ``` +- Fix the `Product` method code so it returns the product. Save the file. -2. Run `dotnet watch test`. - - If you previously fixed the bug in the `MathController` then you'll see an output similar to the one below, otherwise you'll see a test failure: - - ```bash - WebAppTests user$ dotnet watch test - [DotNetWatcher] info: Running dotnet with the following arguments: test - [DotNetWatcher] info: dotnet process id: 40193 - Project WebApp (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation. - Project WebAppTests (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation. - xUnit.net .NET CLI test runner (64-bit .NET Core osx.10.11-x64) - Discovering: WebAppTests - Discovered: WebAppTests - Starting: WebAppTests - Finished: WebAppTests - === TEST EXECUTION SUMMARY === - WebAppTests Total: 2, Errors: 0, Failed: 0, Skipped: 0, Time: 0.259s - SUMMARY: Total: 1 targets, Passed: 1, Failed: 0. - [DotNetWatcher] info: dotnet exit code: 0 - [DotNetWatcher] info: Waiting for a file to change before restarting dotnet... - ``` - - Once all the tests run, the watcher will indicate that it's waiting for a file to change before restarting `dotnet test`. - -3. Open the controller file in *WebApp/Controllers/MathController.cs* and change some code. If you haven't fixed the product bug, do it now. Save the file. - -`dotnet watch` detects the file change and reruns the tests. The console output will show messages similar to the one below: - -```bash -[DotNetWatcher] info: File changed: /Users/user/dev/aspnet/Docs/aspnet/tutorials/dotnet-watch/sample/WebApp/Controllers/MathController.cs -[DotNetWatcher] info: Running dotnet with the following arguments: test -[DotNetWatcher] info: dotnet process id: 40233 -Project WebApp (.NETCoreApp,Version=v1.0) will be compiled because inputs were modified -Compiling WebApp for .NETCoreApp,Version=v1.0 -Compilation succeeded. - 0 Warning(s) - 0 Error(s) -Time elapsed 00:00:03.2127590 -Project WebAppTests (.NETCoreApp,Version=v1.0) will be compiled because dependencies changed -Compiling WebAppTests for .NETCoreApp,Version=v1.0 -Compilation succeeded. - 0 Warning(s) - 0 Error(s) -Time elapsed 00:00:02.1204052 - -xUnit.net .NET CLI test runner (64-bit .NET Core osx.10.11-x64) - Discovering: WebAppTests - Discovered: WebAppTests - Starting: WebAppTests - Finished: WebAppTests -=== TEST EXECUTION SUMMARY === - WebAppTests Total: 2, Errors: 0, Failed: 0, Skipped: 0, Time: 0.260s -SUMMARY: Total: 1 targets, Passed: 1, Failed: 0. -[DotNetWatcher] info: dotnet exit code: 0 - -[DotNetWatcher] info: Waiting for a file to change before restarting dotnet... -``` +`dotnet watch` detects the file change and reruns the tests. The console output will show the tests passed. diff --git a/aspnetcore/tutorials/dotnet-watch/sample/WebApp/Controllers/MathController.cs b/aspnetcore/tutorials/dotnet-watch/sample/WebApp/Controllers/MathController.cs index 17956650c0..8edc916b8a 100644 --- a/aspnetcore/tutorials/dotnet-watch/sample/WebApp/Controllers/MathController.cs +++ b/aspnetcore/tutorials/dotnet-watch/sample/WebApp/Controllers/MathController.cs @@ -11,8 +11,9 @@ namespace WebApp.Controllers public static int Product(int a, int b) { - // We have an intentional bug here - // + should be * + // We have an intentional bug here. + // change to: + // return a * b; return a + b; } } diff --git a/aspnetcore/tutorials/dotnet-watch/sample/WebApp/Program.cs b/aspnetcore/tutorials/dotnet-watch/sample/WebApp/Program.cs index 2d0ed5af5d..cd6b844cd4 100644 --- a/aspnetcore/tutorials/dotnet-watch/sample/WebApp/Program.cs +++ b/aspnetcore/tutorials/dotnet-watch/sample/WebApp/Program.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; +using Microsoft.AspNetCore.Hosting; using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Builder; namespace WebApp { diff --git a/aspnetcore/tutorials/dotnet-watch/sample/WebApp/Startup.cs b/aspnetcore/tutorials/dotnet-watch/sample/WebApp/Startup.cs index 585054d319..9929c4cb0b 100644 --- a/aspnetcore/tutorials/dotnet-watch/sample/WebApp/Startup.cs +++ b/aspnetcore/tutorials/dotnet-watch/sample/WebApp/Startup.cs @@ -1,24 +1,11 @@ using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; namespace WebApp { public class Startup { - public Startup(IHostingEnvironment env) - { - var builder = new ConfigurationBuilder() - .SetBasePath(env.ContentRootPath) - .AddEnvironmentVariables(); - Configuration = builder.Build(); - } - public IConfigurationRoot Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // Add framework services. @@ -26,11 +13,8 @@ namespace WebApp } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app) { - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); - app.UseMvc(); } } diff --git a/aspnetcore/tutorials/dotnet-watch/sample/WebApp/WebApp.csproj b/aspnetcore/tutorials/dotnet-watch/sample/WebApp/WebApp.csproj new file mode 100644 index 0000000000..39bffc9f81 --- /dev/null +++ b/aspnetcore/tutorials/dotnet-watch/sample/WebApp/WebApp.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp1.1 + + + + + + + + + + + + diff --git a/aspnetcore/tutorials/dotnet-watch/sample/WebApp/project.json b/aspnetcore/tutorials/dotnet-watch/sample/WebApp/project.json deleted file mode 100644 index 639dbf6624..0000000000 --- a/aspnetcore/tutorials/dotnet-watch/sample/WebApp/project.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "dependencies": { - "Microsoft.NETCore.App": { - "version": "1.0.0", - "type": "platform" - }, - "Microsoft.AspNetCore.Mvc": "1.0.0", - "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", - "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", - "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", - "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", - "Microsoft.Extensions.Configuration.Json": "1.0.0", - "Microsoft.Extensions.Logging": "1.0.0", - "Microsoft.Extensions.Logging.Console": "1.0.0", - "Microsoft.Extensions.Logging.Debug": "1.0.0", - "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0" - }, - "tools": { - "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-*" - }, - "frameworks": { - "netcoreapp1.0": { - "imports": [ - "dotnet5.6", - "portable-net45+win8" - ] - } - }, - "buildOptions": { - "emitEntryPoint": true, - "preserveCompilationContext": true - }, - "runtimeOptions": { - "configProperties": { - "System.GC.Server": true - } - }, - "publishOptions": { - "include": [ - "web.config" - ] - }, - "scripts": { - "postpublish": [ - "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" - ] - } -} \ No newline at end of file diff --git a/aspnetcore/tutorials/dotnet-watch/sample/WebApp/web.config b/aspnetcore/tutorials/dotnet-watch/sample/WebApp/web.config deleted file mode 100644 index dc0514fca5..0000000000 --- a/aspnetcore/tutorials/dotnet-watch/sample/WebApp/web.config +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - diff --git a/aspnetcore/tutorials/dotnet-watch/sample/WebAppTests/WebAppTests.csproj b/aspnetcore/tutorials/dotnet-watch/sample/WebAppTests/WebAppTests.csproj new file mode 100644 index 0000000000..2493f02e6f --- /dev/null +++ b/aspnetcore/tutorials/dotnet-watch/sample/WebAppTests/WebAppTests.csproj @@ -0,0 +1,22 @@ + + + + netcoreapp1.1 + + + + + + + + + + + + + + + + + + diff --git a/aspnetcore/tutorials/dotnet-watch/sample/WebAppTests/project.json b/aspnetcore/tutorials/dotnet-watch/sample/WebAppTests/project.json deleted file mode 100644 index 55ce8f4ec6..0000000000 --- a/aspnetcore/tutorials/dotnet-watch/sample/WebAppTests/project.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "version": "1.0.0-*", - "dependencies": { - "Microsoft.NETCore.App": { - "version": "1.0.0", - "type": "platform" - }, - "dotnet-test-xunit": "1.0.0-*", - "NETStandard.Library": "1.6.0", - "WebApp": "1.0.0-*", - "xunit": "2.1.0" - }, - "frameworks": { - "netcoreapp1.0": { - "imports": [ - "dnxcore50", - "portable-net451+win8" - ] - } - }, - "tools": { - "Microsoft.DotNet.Watcher.Tools": "1.0.0-*" - }, - "testRunner": "xunit" -} \ No newline at end of file diff --git a/aspnetcore/tutorials/dotnet-watch/sample/global.json b/aspnetcore/tutorials/dotnet-watch/sample/global.json deleted file mode 100644 index 6e517aa9eb..0000000000 --- a/aspnetcore/tutorials/dotnet-watch/sample/global.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "projects": [ "WebApp", "WebAppTests" ], - "sdk": { - "version": "1.0.0-preview2-1-003177" - } -} \ No newline at end of file