In one article, you can quickly read .NET CLI!

dotnet cli is one of the most useful features of .Net Core. In this article, we will introduce how several .Net OSS tools use dotnet cli and how to use the new cli tool in daily development.

text

Key points

  • dotnet cli makes automation and scripting based on .Net projects very simple, especially compared to .Net technology more than a decade ago.
  • The dotnet cli scalability model creates the conditions that make it possible to integrate command-line programs written in external .NET into your automated build via Nuget.
  • dotnet cli allows you to test the solution in your build script.
  • The test output of dotnet cli helps to use continuous integration (CI) better.
  • Using container technology like Docker is much easier than using dotnet cli.

With the release of .NET Core 2.0, Microsoft has the next major version of the universal, modular, cross-platform and open source platform, which was originally released in 2016. .NET Core has created many APIs, which are available in the current version of the .NET framework. It was originally created for the next-generation ASP.NET solution, but it is now the driving force and foundation for many other scenarios, including the Internet of Things, cloud, and next-generation mobile solutions. In the second series of articles on .NET Core, we will further explore the advantages of .NET Core and how it benefits not only traditional .NET developers, but also all those who need to provide the market with robust and efficient And economical solutions for technical staff.

Someone has recently asked me, what are the advantages of choosing .NET Core compared to those who either hesitate or cannot withdraw from the old, full-featured .NET? I will mention in my answer that .NET Core has better performance, improved csproj file format, improved ASP testability, and it is cross-platform.

As the author of several OSS tools (Marten, StructureMap, and Alba cited as an example in this project), the biggest advantage for me personally may be the emergence of dotnet cli. I personally think that when used in conjunction with the new .NET SDK csproj file format, the dotnet cli tool makes it easier for me to create projects and maintain build scripts. I can run tests in build scripts more easily, use and distribute Nuget packages more easily, and the cli extensibility mechanism is ideal for merging custom executable files distributed through Nuget packages into automatic builds.

To start using dotnet cli, first install the .NET SDK on the development machine. After the installation is complete, give you some useful tips:

  • Install the "dotnet" tool globally in your PATH so that it can be used from the command line prompt anywhere.
  • dotnet cli adopts Linux-style command syntax, using "–word [value]" to express the selected parameter, or directly using the abbreviated form "-w [value]". If you are used to Git or Node.js command line tools, you will not be strange to dotnet cli.
  • "Dotnet --help" will list the installed commands and some basic syntax usage.
  • "Dotnet --info" will tell you which version of dotnet cli you are using. It may be a good idea to call this command in a continuous integration build to work locally and troubleshoot when the build server fails, and vice versa.
  • Although I am talking about .NET Core in this article, please note that you can use the new SDK project format and dotnet cli in previous versions of the full .NET framework.

Hello World on the command line

To briefly understand some of the highlights of dotnet cli, let us assume that we want to build a simple "Hello World" ASP.NET Core application. However, for fun, let's add some new tricks:

1. Our web service will be tested automatically in a separate project.

2. We will deploy our service through a Docker container because this is a cool practice (it shows more dotnet cli).

3. Of course, we will use dotnet cli as much as possible.

If you want to see the final result of this code, please check this GitHub repository.

First, let's start with an empty directory called "DotNetCliArticle" and open your favorite command line tool to that directory. We will start by using the "dotnet new" command to generate solution files and new projects. The .NET SDK comes with several common templates for creating common project types or files, and other templates that can be used as add-ins (more on this later). To view the templates available on your machine, you can use the following command dotnet new -help, it should give the following output:

In one article, you can quickly read .NET CLI!

 

 

You may notice that there is a sln template, which is for an empty solution file. We will use the template and type the dotnet new sln command, which will produce the following output:

Copy code

The template "Solution File" was created successfully.

By default, this command will name the solution file after the included directory. Because I named the root directory "DotNetCliArticle", the generated solution file is "DotNetCliArticle.sln".

Next, let's add the actual project of "Hello, World" with the following command:

Copy code

dotnet new webapi --output HeyWorld

The above command means to use the "webapi" template in the "HeyWorld" selected by the "output" parameter. This template will generate a streamlined MVC Core project structure suitable for headless APIs. Similarly, the default method is to name the project file according to the directory where it is located, so we get a file named "HeyWorld.csproj" and all the basic files in the directory to form a minimal ASP.NET MVC Core API project. The template also sets up all necessary Nuget references to ASP.NET Core, which we will use when we start a new project.

Since I happened to build it in a small Git repository, after using Git add to add any new files, I used Git status to view the newly created files:

Copy code

 new file: HeyWorld/Controllers/ValuesController.cs
new file: HeyWorld/HeyWorld.csproj
new file: HeyWorld/Program.cs
new file: HeyWorld/Startup.cs
new file: HeyWorld/appsettings.Development.json
new file: HeyWorld/appsettings.json

Now, to add a new project to our empty solution file, you can use the "dotnet sln" command like this:

Copy code

dotnet sln DotNetCliArticle.sln add HeyWorld/HeyWorld.csproj

Now we have a new ASP.NET Core API service as a shell, without opening Visual Studio.NET (or JetBrains Rider). To go further, to start our test project before writing any actual code, I issue the following command:

Copy code

dotnet new xunit --output HeyWorld.Tests
dotnet sln DotNetCliArticle.sln add HeyWorld.Tests/HeyWorld.Tests.csproj

The above command uses xUnit.NET to create a new project and add the new project to our solution file. The test project needs a reference to the "HeyWorld" project. Fortunately, we can use the great "dotnet add" tool to add the project reference as follows:

Copy code

dotnet add HeyWorld.Tests/HeyWorld.Tests.csproj reference HeyWorld/HeyWorld.csproj

Before opening the solution, I knew there were some Nuget references, and I wanted to use them in the test project. The assertion tool I chose is Shoully, so I will add a reference to the latest version of shoully by issuing another call to the command line:

Copy code

dotnet add HeyWorld.Tests/HeyWorld.Tests.csproj package Shouldly

The output of the command line is as follows:

Copy code

info : Adding PackageReference for package 'Shouldly' into project 'HeyWorld.Tests/HeyWorld.Tests.csproj'.
log : Restoring packages for /Users/jeremydmiller/code/DotNetCliArticle/HeyWorld.Tests/HeyWorld.Tests.csproj...
info : GET https://api.nuget.org/v3-flatcontainer/shouldly/index.json
info : OK https://api.nuget.org/v3-flatcontainer/shouldly/index.json 109ms
info : Package 'Shouldly' is compatible with all the specified frameworks in project 'HeyWorld.Tests/HeyWorld.Tests.csproj'.
info : PackageReference for package 'Shouldly' version '3.0.0' added to file '/Users/jeremydmiller/code/DotNetCliArticle/HeyWorld.Tests/HeyWorld.Tests.csproj'.

Next, I want to add at least one Nuget reference to the test project named Alba. I will use AspNetCore2 to write HTTP contract tests for new web applications:

Copy code

dotnet add HeyWorld.Tests/HeyWorld.Tests.csproj package Alba.AspNetCore2

Now, before using the code to check, I will issue the following command on the command line to build all the projects in the solution to ensure that they all compile properly:

Copy code

dotnet build DotNetCliArticle.sln

Due to the conflict between the diamond-dependent versions of the references between Alba.AspNetCore2 and ASP.NET Core Nuget in the HeyWorld project, there is no compilation. But don't worry, because this problem is easy to solve, just fix the version dependency of Microsoft.AspNetCore. All Nuget in the test project looks like this:

Copy code

dotnet add HeyWorld.Tests/HeyWorld.Tests.csproj package Microsoft.AspNetCore.All --version 2.1.2

In the above example, using the "--version" flag with a value of "2.1.2" will fix the reference to that version, not just the latest version found in the Nuget feed.

In order to check again whether our Nuget dependency problem has been solved, we can use the following command to check, it is faster than recompiling everything:

Copy code

dotnet clean && dotnet restore DotNetCliArticle.sln

As an experienced .NET developer, I am very worried about the files remaining in the temporary / obj and / bin folders. Therefore, I use the "Clean Solution" command in Visual Studio in case I try to change what is dropped when I refer to it. Executing the "dotnet clean" command from the command line is the exact same operation.

Similarly, for the well-known Nuget dependency problem, the "dotnet restore" command tried to solve it in the solution. In this case, using "dotnet restore" allows us to quickly find any potential conflicts or missing Nuget references without having to perform a full compilation. I mainly use this command in my work. In the latest version of dotnet cli, when you call "dotnet build / test / pack / etc", Nuget parsing will be done automatically for you (this behavior can be overwritten with tags), which will first require Nuget.

The "dotnet restore DotNetCliArticle.sln" we called finished running cleanly and without errors, so we can finally prepare to write some code. Let's open the C # editor of your choice and add a code file to HeyWorld. The test project contains a very simple HTTP protocol test that will specify the behavior we want to get from the "GET: /" route in the new HeyWorld application:

Copy code

using System.Threading.Tasks;
using Alba;
using Xunit;
namespace HeyWorld.Tests
{
public class verify_the_endpoint
{
[Fact]
public async Task check_it_out()
{
using (var system = SystemUnderTest.ForStartup<Startup>())
{
await system.Scenario(s =>
{
s.Get.Url("/");
s.ContentShouldBe("Hey, world.");
s.ContentTypeShouldBe("text/plain; charset=utf-8");
});
}
}
}
}

The result file should be saved in the HeyWorld.Tests directory with an appropriate name (such as verify_the_endpoints.cs).

Before we have a deep understanding of the Alba mechanism, the home page routing of our new HeyWorld application should write "Hey, world". Although we haven't written any actual code in the HeyWorld application, we can still run this test to see if it can connect correctly, or it fails for some "reasonable reason".

Back at the command line, I can use the following command to run all the tests in the test project:

Copy code

dotnet test HeyWorld.Tests/HeyWorld.Tests.csproj

One of our tests will fail because nothing has been implemented yet, it gives us this output:

Copy code

Build started, please wait...
Build completed.
Test run for /Users/jeremydmiller/code/DotNetCliArticle/HeyWorld.Tests/bin/Debug/netcoreapp2.1/HeyWorld.Tests.dll(.NETCoreApp,Version=v2.1)
Microsoft (R) Test Execution Command Line Tool Version 15.7.0
Copyright (c) Microsoft Corporation. All rights reserved.
Starting test execution, please wait...
Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 2.4565 Seconds

To sum the output, a test was executed, but it failed. We can also see the standard xUnit output, which provides some information about why the test failed. It should be noted here that the "dotnet test" command will return an exit code. If all tests pass, it returns 0, indicating success; if any test fails, it returns a non-zero exit code, indicating failure. This is very important for continuous integration (CI) scripts, and most CI tools use the exit code of any command to determine when the build fails.

I think the above test failed because of the "reasonable reason", which means that the test tool seems to be able to guide the real application, and I want to get a 404 response because no code has been written yet. Next, let's implement an MVC Core endpoint for the expected behavior:

Copy code

public class HomeController : Controller
{
[HttpGet("/")]
public string SayHey()
{
return "Hey, world!";
}
}

(Note that the previous code should be added as an additional class in the HeyWorld \ startup.cs file)

Back to the command line again, let us run the previous "dotnet test HeyWorld.Tests / HeyWorld.Tests.csproj" command, hoping to see this result:

Copy code

Build started, please wait...
Build completed.
Test run for /Users/jeremydmiller/code/DotNetCliArticle/HeyWorld.Tests/bin/Debug/netcoreapp2.1/HeyWorld.Tests.dll(.NETCoreApp,Version=v2.1)
Microsoft (R) Test Execution Command Line Tool Version 15.7.0
Copyright (c) Microsoft Corporation. All rights reserved.
Starting test execution, please wait...
Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.
Test Run Successful.
Test execution time: 2.4565 Seconds

Ok, now that the test has passed, let's run the actual application. Since the "dotnet new webapi" template uses in-process Kestrel web server to process HTTP requests, the only thing we need to do to run the new HeyWorld application is to start it from the command line using the following command:

Copy code

 dotnet run --project HeyWorld/HeyWorld.csproj

Running the above command should result in the following output:

Copy code

Using launch settings from HeyWorld/Properties/launchSettings.json...
: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
User profile is available. Using '/Users/jeremydmiller/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
Hosting environment: Development
Content root path: /Users/jeremydmiller/code/DotNetCliArticle/HeyWorld
Now listening on: https://localhost:5001
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

To test the new application we are running now, simply navigate in the browser as follows:

In one article, you can quickly read .NET CLI!

 

 

Handling HTTPS settings is beyond the scope of this article.

Please note again that I assume that all commands are executed with the current directory set as the solution root folder. If the current directory is a project directory and there is only one * .csproj. Then, you only need to type "dotnet run" in the directory. Now that we have a tested web api application, let's put HeyWorld in the Docker image. Using the standard template for dockerizing a .NET Core application, we will add a Dockerfile to the HeyWorld project with the following content:

Copy code

FROM microsoft/dotnet:sdk AS build-env
WORKDIR /app
Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
Build runtime image
FROM microsoft/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "HeyWorld.dll"]

(Note that the previous text should be saved in a text file named Dockerfile in the project directory—HeyWorld \ Dockerfile in this example).

Because this article is only about dotnet cli, I just want to focus on two uses of it in the Dockerfile:

1. "dotnet restore"-As we learned above, this command will resolve any Nuget dependencies of the application.

2. The "dotnet publish -c Release -o out"-"dotnet publish" command will build the specified project and copy all the files that make up the application to the given location. In our example, "dotnet publish" will copy the compiled assemblies, all assemblies referenced from Nuget dependencies, configuration files, and any files referenced in the csproj file for HeyWorld itself.

Please note that in the above usage, we must explicitly tell "dotnet publish" to compile with the "Release" configuration by using the "-c Release" flag. Those dotnet cli commands used for encoding (such as "build", "publish", "pack") if not specified, will use "Debug" as the default value. Pay attention to this behavior, if you want to release Nuget or applications for production, remember to specify "-c Release" or "-configuration Release". Don't blame me for not reminding you.

To complete the entire cycle, we can now use the following commands to build and deploy our small HeyWorld application via Docker:

Copy code

docker build -t heyworld .
docker run -d -p 8080:80 --name myapp heyworld

The first command builds and publishes the Docker image locally for our application "heyworld". The second command actually runs our application as a Docker container named "myapp". You can open the browser to visit "http: // localhost: 8080" to verify.

to sum up

dotnet cli makes automation and scripting based on .NET projects very simple, especially compared to .NET technology more than a decade ago. In many cases, you may even avoid any task-based build script tools (Cake, Fake, Rake, Psake, etc.) and choose simple shell scripts that are only delegated to dotnet cli. In addition, the dotnet cli scalability model makes it easy to distribute external .NET authorized command-line applications to automatic build programs via Nuget.

About the author Jeremy Miller (Jeremy Miller) grew up in a farming community in Missouri, where there is a group of "special" people named "Shade Mechanics". Usually, they are not the most prestigious people in the world, but they have the know-how to solve mechanical problems and are reckless and fearless. If you find that two legs are sticking out from a commuter car parked in the block, he must be a repairman. He is surrounded by skeleton cars, piled in his bushy, garbage-filled yard . The beaters you see abandoned around him are not useless, they are material. He will make small adjustments piecemeal, and then come up with a creative solution based on your needs. Despite its reputation, a shade mechanic knows how to get things running. Although Miller does not have any special mechanical abilities (although he has a degree in mechanical engineering), he likes to think of himself as a developer like a shade mechanic. Shards of abandoned open source projects must be everywhere on his hard drive. With the release of .NET Core 2.0, Microsoft has the next major version of the universal, modular, cross-platform and open source platform, which was originally released in 2016. .NET Core has created many APIs, which are available in the current version of the .NET framework. It was originally created for the next-generation ASP.NET solution, but it is now the driving force and foundation for many other scenarios, including the Internet of Things, cloud, and next-generation mobile solutions. In the second series of articles on .NET Core, we will further explore the advantages of .NET Core and how it benefits not only traditional .NET developers, but also all those who need to provide the market with robust and efficient And economical solutions for technical staff.

If you have any questions, please contact: e-commerce training . Hashiguchi Chiyomi

Guess you like

Origin www.cnblogs.com/qilundianshang/p/12718370.html