使用VsCode編寫和調試.NET Core項目

​ 原本我還想介紹如下VSCode或者donet core,可是發現都是廢話,沒有必要,你們若是對這個不瞭解能夠直接google這兩個關鍵字,或者也根本不會看我這邊文章。前端

​ 好直接進入主題了,本文的前提條件:git

  1. 已經安裝好了.NET Core SDK
  2. 已經安裝了VSCode

0x00. 磨刀不誤砍柴工

使用VSCode編寫dotnet core項目除了其 默認的功能外,我推薦還要安裝一些很是有特點,而且有用的擴展,正是由於VSCode的插件機制,才讓它變得更增強大,知足咱們各式各樣的需求github

C#語言擴展: https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp
這個是使用VSCode編寫C#代碼必須的,安裝以後在默認打開.cs文件時 還會自動下載調試器等(不過過程可能比較慢,在牆外的緣由)
[C# XML註釋]: https://marketplace.visualstudio.com/items?itemName=k--kato.docomment
這個能夠插件能夠快速的幫你添加註釋,選擇安裝吧
[C# Extensions]: https://marketplace.visualstudio.com/items?itemName=jchannon.csharpextensions
這個插件,強烈推薦,能夠幫你在創建文件的時候初始化文件內容包括對應的命名空間等shell

還有一些其餘輔助類的,好比EditorConfig,Guildes,One Dark Theme,Project Manager ,Setting Sync等。json

0x01. 新建多項目解決方案

打開命令行工具,在命令行工具中輸入:c#

$:> dotnet new sln -o vscode_tutorial //在當前目錄下 建立名爲vscode_tutorial

以上命令使用dotnet sdk,新建一個解決方案文件,你能夠不用命令行手動建立,可是使用dotnet new 能夠更加方便的建立dotnet core相關的項目. 順便提一下使用dotnet new 命令能夠新建類庫項目,控制檯項目,網站項目等等,詳細使用可使用dotnet help new 命令來查看,以下圖所示:windows

建完解決方案咱們要來創建項目了,包括一個控制檯項目,一個類庫項目和一個單元測試項目app

首先創建一個公共的類庫項目用於存放咱們的業務方法(假設咱們在作一個真實的項目)函數

$:> dotnet new classlib -o VSCodeTutorial.Common //在當前目錄下新建類庫項目VSCodeTutorial.Common
$:> dotnet sln add VSCodeTutorial.Common/VSCodeTutorial.Common.csproj //將項目添加到解決方案中

經過一樣的方式,咱們創建好控制檯項目和單元測試項目grunt

$:> dotnet new console -o VSCodeTutorial.ConsoleApp
$:> dotnet sln add VSCodeTutorial.ConsoleApp/VSCodeTutorial.ConsoleApp.csproj
$:> dotnet new xunit -o VSCodeTutorial.UnitTest
$:> dotnet sln add VSCodeTutorail.UnitTest/VSCodeTutorial.UnitTest.csproj

這裏要注意控制的模板名稱叫console而單元測試咱們使用xunit

這個時候咱們的項目結構已經創建完成了,咱們用VsCode來打開當前目錄來看看完成的項目結構吧,以下圖所示

0x02. 添加項目間的依賴關係

使用VsCode打開項目文件VSCodeTutorial.ConsoleApp.csproj,在其中添加對Common項目的引用

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>
 <!--添加項目引用-->
  <ItemGroup>
    <ProjectReference Include="..\VSCodeTutorial.Common\VSCodeTutorial.Common.csproj" />
  </ItemGroup>
</Project>

一樣打開VSCodeTutorial.UnitTest.csproj項目文件,在其中添加對Common項目的引用

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>
<!--nuget 上的類庫引用-->
  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
    <PackageReference Include="xunit" Version="2.2.0" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
  </ItemGroup>
<!--本地項目引用-->
 <ItemGroup>
    <ProjectReference Include="..\VSCodeTutorial.Common\VSCodeTutorial.Common.csproj" />
  </ItemGroup>
</Project>

和上面的那個項目不一樣,這裏有一些額外的依賴,這裏能夠恰好了解下,若是添加nuget中包的依賴,只需像上面同樣使用PackageReference並填入類庫名稱和版本號便可

添加完依賴後,咱們在根目錄下使用dotnet restore來初始化如下,也能夠再用dotnet build命令來嘗試編譯一下先

項目依賴關係如圖2:

0x03. 開始編寫代碼

​ 這個項目的總體需求:我須要打開一個控制檯程序,運行時須要用戶輸入一個小於50的整數,控制檯接收到這個數字後計算出這個數字的階乘,並把結果輸出到控制檯上。

​ 通過簡單的思考,我決定把階乘的實現放到Common項目中,而且對其進行單元測試,測試的代碼則放到UnitTest項目中

首先咱們把以前生成的項目中不須要的文件給刪除掉VsCodeTutorial.Common中的Class1.cs和VSCodeTutorial.UnitTest中的UnitTest1.cs ,固然你也能夠留着。

第一步,咱們在VsCodeTutorial.Common項目中新建文件MathHelper.cs並在文件中添加以下代碼,實現咱們的階乘,代碼比較簡單就不詳述了。

namespace VSCodeTutorial.Common
{
    public class MathHelper
    {
        /// <summary>
        /// 階乘,本例中暫不考慮 溢出的問題哦 Factorial(n) = n*(n-1)*(n-2)...*1;
        /// </summary>
        /// <param name="n">輸入參數n</param>
        /// <returns></returns>
        public static int Factorial(int n){
            if(n <=0 ){
                throw new System.ArgumentOutOfRangeException("n","參數錯誤,不能小於等於零");
            }
            if(n == 1){
                return 1;
            }
            return n*Factorial(n-1);
        }
    }
}

第二步,咱們要來測試這個代碼,看看是否達到了咱們的目標,在VSCodeTutorial.UnitTest項目中新建文件MathHelpTest.cs向文件中添加測試Factorial函數的方法,以下所示:

using System;
using VSCodeTutorial.Common;
using Xunit;

namespace VSCodeTutorial.UnitTest
{
    public class MathHelperTest
    {
         [Fact]
        public void TestFactorial()
        {
            //先測試一下邊界的狀況
            int zero = 0 ;
            var exception = Assert.Throws<ArgumentOutOfRangeException>(() => MathHelper.Factorial(zero));

            int one = 1;
            var oneResult = MathHelper.Factorial(one);
            Assert.Equal(1, oneResult);

            //再測一下正常的狀況
            int five = 5;
            var fiveResult = MathHelper.Factorial(five);
            Assert.Equal(5*4*3*2*1, fiveResult);

            int ten = 10;
            var tenResult = MathHelper.Factorial(ten);
            Assert.Equal(10*9*8*7*6*5*4*3*2*1, tenResult);
        }
    }
}

0x04 使用命令行運行單元測試

​ 在使用配置VSCode以前 我仍是建議你們先使用命令行來運行一下單元測試,這有利於更好的理解配置內容。

在根目錄下輸入命令:dotnet test ./VSCodeTutorial.UnitTest/VSCodeTutorial.UnitTest.csproj 查看運行結果:

不好勁會出現編碼錯誤,並且這個錯誤暫時尚未辦法解決..可是我猜單元測試經過了,這個問題相信在後續的版本中確定會獲得解決,事實上在Console項目中是能夠解決輸出亂碼問題的。不過可喜的是在VSCode中運行單元測試是沒有亂碼的問題的😁。

0x05 使用VSCode 運行單元測試

首先當你打開項目的時候,VSCode 可能已經建議你配置一下相關的內容,以下圖所示:

選擇Yes, 會幫你新建這個一個目錄和兩個文件,luanch.json是用來執行調試程序的配置,而tasks.json則是配置各類任務的,其中運行單元測試就是一種任務。

首先咱們打開tasks.json ,默認已經添加好了一個任務,以下所示

{
    "version": "0.1.0",
    "command": "dotnet", //全局命令,即全部的任務都使用這個命令,也能夠在各個任務中設置
    "isShellCommand": true,
    "args": [],
    "tasks": [
        {
            "taskName": "build", //任務名稱 當設置了主的command 以後這個taskName也會做爲一個命令參數
            "args": [
                "${workspaceRoot}\\VSCodeTutorial.ConsoleApp\\VSCodeTutorial.ConsoleApp.csproj"
            ],
            "isBuildCommand": true, //一個解決方案只能設置一個編譯任務,多設置了也是白搭,固然也能執行,只是不能利用快捷方式運行了
            "problemMatcher": "$msCompile"//C#項目的problemMatcher
        }
    ]
}

默認使用了全局命令行,這樣能夠在任務中省去配置dotnet命令,可是若是你的解決方案中包括多個項目須要不一樣的命令行編譯方式,若是前端網站使用grunt打包資源,那麼頂部應該留空,而在各個子任務中配置command。還有若是存在多個編譯項目時(如客戶端和服務端在一個解決方案時),也應該把command配置在子任務中,並設置個性化的taskName以便區別,因此我推薦把command設置在任務中,下面咱們修改一下以上代碼,並添加一個運行單元測試的人。

{
    "version": "0.1.0",
    "isShellCommand": true,
    "args": [],
    "tasks": [
        {
            "taskName": "build_console",
            "command":"dotnet"
            "args": [
                "build", //組成dotnet build
                //設置須要編譯的項目,若是存在多個啓動項目能夠設置成解決方案文件(.sln),這裏只有一個項目因此設置運行項目也能夠
                "${workspaceRoot}\\VSCodeTutorial.ConsoleApp\\VSCodeTutorial.ConsoleApp.csproj"
            ],
            "isBuildCommand": true, //設置是否編譯項目
            "problemMatcher": "$msCompile"
        },
        {
            "taskName": "UnitTest",
            "command":"dotnet",
            "args": [
                "test",//組成dotnet test 命令
                "${workspaceRoot}\\VSCodeTutorial.UnitTest\\VSCodeTutorial.UnitTest.csproj"
            ],
            "isTestCommand": true,//設置爲單元測試項目
            "problemMatcher": "$msCompile"
        }
    ]
}

上面的代碼中,我將command命令移到了任務中,並給每一個任務起了一個好識別的名字,如今這裏一個有2個任務了

第一個任務build_console 運行時 會編譯VSCodeTutorial.ConsoleApp項目及其依賴的項目

第二個任務UnitTest則是單元測試項目,運行dotnet test命令,這裏有個特殊的設置就是"isTestCommand": true 標識爲測試項目後能夠經過快捷方式運行該命令

任務建好了,咱們來運行任務把,windows按下 ctrl+shift+p,在彈出的對話框中輸入:task 過濾命令能夠獲得如下的選項

選擇任務:運行測試任務 這條來運行咱們以前編寫好的單元測試項目,能夠看到運行成功的狀況,以下圖所示

這裏中文顯示正常,沒有亂碼哦,可是我不知道是什麼緣由..就是這麼神奇

對於常常執行的任務,能夠經過設置鍵盤快捷方式來方便調用,能夠看到我分別設置了ctrl+shift+t 運行測試任務ctrl+shift+b 運行編譯任務,ctrl+shift+r 啓動選擇任務,你們能夠根據本身的喜愛來設置。

0x06 開始編寫控制檯代碼

打開VSCodeTutorial.ConsoleApp項目中的Program.cs文件,修改其中的代碼,以下所示

using System;
using VSCodeTutorial.Common;

namespace VSCodeTutorial.ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            while(true)
            {
                Console.WriteLine("請輸入一個小於10的數字,回車結束:");
                string input_str = Console.ReadLine();
                if(int.TryParse(input_str ,out var input_int))
                {
                    if(input_int>0 && input_int<=10){
                       int result =  MathHelper.Factorial(input_int);
                       Console.WriteLine("你輸入的數字是{0},它的階乘結果是{1},退出請按ctrl+c,按其餘鍵再試一次",input_int,result);
                       Console.ReadKey();
                    }
                }
                else{
                    Console.WriteLine("輸入的字符不是有效的數字");
                }
            }

        }
    }
}

代碼比較 簡單,就不作解釋了,咱們直接來看運行的結果,這裏順便提一下啊,在咱們以前作的衆多工做以後,咱們這裏編寫代碼有美美噠的智能提示哦,以下圖所示:

好,再根目錄下輸入如下命令運行ConsoleApp

$:> dotnet run -p ./VSCodeTutorial.ConsoleApp/VSCodeTutorial.ConsoleApp.csproj

也能夠在VSCodeTutorial.ConsoleApp 目錄下直接運行dotnet run 命令便可.

結果運行仍是亂碼中,可是此次咱們有辦法解決,咱們在控制檯代碼中添加一句代碼便可onsole.OutputEncoding = Encoding.UTF8

using System;
using System.Text;
using VSCodeTutorial.Common;

namespace VSCodeTutorial.ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8; // 設置控制檯編碼
            while(true)
            {
                Console.WriteLine("請輸入一個小於10的數字,回車結束:");
                string input_str = Console.ReadLine();
                if(int.TryParse(input_str ,out var input_int))
                {
                    if(input_int>0 && input_int<=10){
                       int result =  MathHelper.Factorial(input_int);
                       Console.WriteLine("你輸入的數字是{0},它的階乘結果是{1},退出請按ctrl+c,按其餘鍵再試一次",input_int,result);
                       Console.ReadKey();
                    }
                }
                else{
                    Console.WriteLine("輸入的字符不是有效的數字");
                }
            }

        }
    }
}

使用dotnet build編譯後,再次運行Console項目看到了咱們指望的界面

程序運行正確,固然了,咱們都跑過單元測試了不是。。

0x07 開始調試程序了

以下圖提示操做

終於輪到咱們以前生成的launch.json文件出場了,先來看下它的代碼,代碼中已經添加了配置的說明

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": ".NET Core Launch (console)", //配置名稱 能夠改爲更好識別的名字
            "type": "coreclr", // .net core類型的調試
            "request": "launch", //調試方式 不用改
            "preLaunchTask": "build", // 前置任務,這裏是編譯,可是默認的編譯任務,已經被我改了名字了,因此這裏要改一下哦
            "program": "${workspaceRoot}\\VSCodeTutorial.ConsoleApp\\bin\\Debug\\netcoreapp1.1\\VSCodeTutorial.ConsoleApp.dll", //須要調試的DLL的位置 
            "args": [], //額外的參數
            "cwd": "${workspaceRoot}\\VSCodeTutorial.ConsoleApp", //工做目錄
            "console": "internalConsole", //控制檯模式,這裏是內嵌控制檯,一會要改爲外置的,否則無法交互輸入
            "stopAtEntry": false,
            "internalConsoleOptions": "openOnSessionStart"
        },
        {
            "name": ".NET Core Attach", //名稱
            "type": "coreclr", //類型
            "request": "attach", //使用附加的方式
            "processId": "${command:pickProcess}" //附加的進程ID
        }
    ]
}

根據實際狀況,須要對上面的配置進行如下變動,變動的部分已經添加了註釋,附加調試不是本文的重點,就不改了

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "調試ConsoleApp", //修改下命令
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build_console", //修改前置任務名和task.json中配置一致
            "program": "${workspaceRoot}\\VSCodeTutorial.ConsoleApp\\bin\\Debug\\netcoreapp1.1\\VSCodeTutorial.ConsoleApp.dll",
            "args": [],
            "cwd": "${workspaceRoot}\\VSCodeTutorial.ConsoleApp",
            "externalConsole":true, //使用外置的控制檯
            "stopAtEntry": false,
            "internalConsoleOptions": "openOnSessionStart"
        },
        {
            "name": ".NET Core Attach",
            "type": "coreclr",
            "request": "attach",
            "processId": "${command:pickProcess}"
        }
    ]
}

修改完成後,咱們點擊運行按鈕能夠開始調試了,調試的方式和使用VS是一致的,快捷鍵爲F5 F10 F11

簡直太強大了!

0x08 多項目啓動調試

有時候咱們會同時在一個解決方案中 同時啓動兩個項目來調試,那麼怎麼配置呢,其實很簡單,另一個項目和以前的同樣各自配置一個編譯的Task(固然最好是兩個項目使用.sln來統一編譯),而後各配置一個launch配置,而後使用compounds 配置來同時啓動便可,示例以下

{
    "version": "0.2.0",
    "configurations": [
        "HelloRpcClientLaunch"
        {
            "name": "HelloRpcServer",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "buildServer",
            "program": "${workspaceRoot}\\src\\sample\\HelloRpc\\HelloRpc.Server\\bin\\Debug\\netcoreapp1.1\\HelloRpc.Server.dll",
            "args": [],
            "cwd": "${workspaceRoot}\\src\\sample\\HelloRpc\\HelloRpc.Server",
            "externalConsole":true,
            "stopAtEntry": false,
            "internalConsoleOptions": "openOnSessionStart"
        },
        "HelloRpcClientLaunch"
        {
            "name": "HelloRpcClient",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "buildClient",
            "program": "${workspaceRoot}\\src\\sample\\HelloRpc\\HelloRpc.Client\\bin\\Debug\\netcoreapp1.1\\HelloRpc.Client.dll",
            "args": [],
            "cwd": "${workspaceRoot}\\src\\sample\\HelloRpc\\HelloRpc.Client",
            "externalConsole":true,
            "stopAtEntry": false,
            "internalConsoleOptions": "openOnSessionStart"
        }
    ]
    "compounds": [
        {
            "name": "Server/Client",
            "configurations": ["HelloRpcServer", "HelloRpcClient"]
        }
    ]
}

這時候就會有個Sever/Client的調試選項供選擇了,如圖:

好了,讓咱們一塊兒使用VSCode來編寫.NetCore項目吧

本文示例代碼 https://github.com/xuanye/VSCodeTutorial

相關文章
相關標籤/搜索