dotnet watch to msbuild (#2746)
* dotnet watch to msbuild * remove white space * clean up * clean up * TD feedbackpull/2897/head
parent
a63cb12f45
commit
58715f7b93
|
@ -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
|
||||
|
||||
<a name=dotnet-watch></a>
|
||||
|
||||
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
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0-msbuild3-final" />
|
||||
</ItemGroup> ```
|
||||
|
||||
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:
|
||||
|
||||
<!-- Command Command with watch 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 -->
|
||||
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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<Project ToolsVersion="15.0" Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0-msbuild3-final" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -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%"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
|
||||
<!--
|
||||
Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
|
||||
-->
|
||||
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
|
||||
</handlers>
|
||||
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
|
||||
</system.webServer>
|
||||
</configuration>
|
|
@ -0,0 +1,22 @@
|
|||
<Project ToolsVersion="15.0" Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WebApp\WebApp.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-*" />
|
||||
<PackageReference Include="Microsoft.DotNet.InternalAbstractions " Version=" 1.0.0-*" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-beta5-build1225" />
|
||||
<PackageReference Include="xunit" Version="2.2.0-beta5-build3474" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0-msbuild3-final" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -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"
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"projects": [ "WebApp", "WebAppTests" ],
|
||||
"sdk": {
|
||||
"version": "1.0.0-preview2-1-003177"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue