.NET开发
C# 和 .NET 是截然不同的。 C# 是一种编程语言语法。 作为语法的一部分,你可以引用和调用 .NET 代码库或程序集中定义的方法。 此外,还可以使用随 .NET SDK 一起安装的 C# 编译器从 C# 代码创建程序集。
应用程序框架合并了几个相关的库,以及初学者项目、文件模板、代码生成器和其他工具。 你可以使用这些资源为特定目的生成整个应用程序。 这些应用程序框架称为“应用模型”。 例如,常用的 .NET 应用程序框架可用于 Web 开发、桌面和移动开发,以及游戏开发等应用模型。
开发环境
可以选择 Visual Studio 2019 或 Visual Studio Code和.NET 软件开发工具包 (SDK)。
.NET SDK
.NET CLI
.NET CLI 概述:https://docs.microsoft.com/zh-cn/dotnet/core/tools/。
dotnet --info # .NET install information
create app
dotnet new console -o myApp # creat project with templates
-o
:创建指定目录以存储项目文件;
可创建的项目类型可通过以下命令查看。
dotnet new -l [<name>]
# Templates Short Name Language Tags
# -------------------- ------------ ------------ --------------
# Console Application console [C#], F#, VB Common/Console
# Class library classlib [C#], F#, VB Common/Library
# ......
运行应用:
cd myApp
dotnet run
NuGet 包管理器
NuGet 是适用于 .NET 的包管理器。 它使开发人员能够创建、共享和使用有用的 .NET 库。 NuGet 客户端工具可生成这些库并将其作为“包”。
访问https://www.nuget.org/packages/查看包的详情。
NuGet 文档:https://docs.microsoft.com/zh-cn/nuget/。
- 若面向.NET Core或.NET Standard,请使用
dotnet
CLI(是SDK项目格式所必需的)。- 要面向.NET Framework(仅限非SDK样式项目),请使用
nuget.exe
CLI。
NU1202: Package is not compatible with net50-windows
:dotnet工具版本太低,升级dotnet
SDK。
配置Nuget仓库
Nuget官方仓库未默认配置(导致无法添加包),通过以下命令配置仓库源。
dotnet nuget add source https://api.nuget.org/v3/index.json -n nuget.org
dotnet nuget list source # 查看注册的软件源
其他软件源相关命令:enable
,disable
,remove
,update
向项目添加包
Visual Studio 和 Visual Studio for Mac 中有一个内置的包管理器命令行和图形用户界面。 可手动向项目文件添加包引用。 也可通过命令行接口 (CLI) 工具(如 Paket 或 .NET Core CLI)进行安装。
运行 dotnet add package <package name>
命令时将抓取和下载所有依赖项。安装的包在项目文件(.csproj
)中列出。
<ItemGroup>
<PackageReference Include="Humanizer" Version="2.8.26" />
</ItemGroup>
如果需要查看项目中的包,可以输入
dotnet list package [--include-transitive]
.NET命令行工具
使用 dotnet tool install <package name>
命令安装工具。
A .NET tool is a special NuGet package that contains a console application.
- global tool: The tool binaries are installed in a default directory that is added to the PATH environment variable.
- global tool in a custom location
- local tool: The .NET CLI uses manifest files to keep track of which tools are installed as local to a directory.
https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools
使用 dotnet new -i <package name>
命令安装模板。
版本控制
语义化版本控制的工作原理是确保包具有版本号,并且该版本号划分为以下部分:
- 主版本。 最左边的数字。 例如 1.0.0 中的 1。 此数字发生更改意味着代码可能出现中断性变更。 可能需要重写部分代码。
- 次要版本。 中间的数字。 例如 1.2.0 中的 2。 此数字发生更改意味着添加了新功能。 你的代码仍可正常工作。 接受更新通常是安全的。
- 修补程序版本。 最右边的数字。 例如 1.2.3 中的 3。 此数字发生更改意味着应用了一个更改,修复了代码中应正常工作的内容。 接受更新应是安全的。
查找和更新过时的包
dotnet list package --outdated [--include-prerelease]
运行 dotnet add package <package name> [--prerelease]
,它将尝试更新到最新版本,可选择传入 --version=<version number/range>
。
生成项目
dotnet build
调试运行
dotnet App.dll >App.log &
可以直接启动动态链接库文件
调试器所具有的两个最重要的功能是:
- 控制程序执行。 你可以暂停程序并逐步运行它,以便查看执行了哪些代码及其对程序状态的影响。
- 观察程序的状态。 例如,你可以在代码执行期间随时查看变量的值和函数参数。
日志记录
-
传统的调试器可能难以调试长期存在的问题。 通过日志,可以对较长的时间跨度进行详细的事后剖析。 与此相反,调试器限制为只能进行实时分析。
-
多线程应用程序和分布式应用程序通常难以调试。 附加调试器往往会修改行为。 可以根据需要分析详细日志,以了解复杂的系统。
-
分布式应用程序中的问题可能是由许多组件之间的复杂交互导致的。 将调试器连接到系统的每个部分可能并不合理。
-
许多服务不应停止。 附加调试器往往会导致超时失败。
-
问题并非总是可预见的。 日志记录和跟踪旨在降低开销,以便在出现问题的情况下可以始终记录程序。
-
System.Console
- 始终启用,并始终写入控制台。
- 适用于客户可能需要在发行版中看到的信息。
- 由于这是最简单的方法,所以常常用于临时调试。 此调试代码通常不会签入到源代码管理中。
- 在非控制台应用程序中使用
System.Console.WriteLine
时,应慎重考虑。
-
System.Diagnostics.Trace
- 仅在定义
TRACE
时启用。 - 写入附加侦听器,默认情况下为 DefaultTraceListener。
- 创建将在大多数生成中启用的日志时,请使用此 API。
- 仅在定义
-
System.Diagnostics.Debug
- 仅在定义
DEBUG
时才启用(处于调试模式时)。 - 写入附加调试器。
- 创建仅在调试生成中启用的日志时,请使用此 API。
- 仅在定义
定义 TRACE 和 DEBUG 常数
在项目文件中添加PropertyGroup
:
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
Debug.Assert(n2 == 5, "The return value is not 5 and it should be.");
ASP.NET Core
RESTful API: adding, viewing, modifying, and removing;
HTTP action verbs : Create, Read, Update, Delete (CRUD).
Entity Framework (EF) Core
概览
API Specification
API | Description | Request body | Response body |
---|---|---|---|
GET /api/Items | Get all items | None | Array of items |
GET /api/Items/{id} | Get item by ID | None | item |
POST /api/Items | Add a new item | To-do item | item |
PUT /api/Items/{id} | Update existing item | To-do item | None |
DELETE /api/Items/{id} | Delete an item | None | None |
创建项目
dotnet new webapi -o dotnet-webapi
cd dotnet-webapi
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.InMemory
dotnet dev-certs https --trust # Trust the HTTPS deve certificate
code .
https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-5.0&tabs=visual-studio-code
编程模型
MVC
Model
Model classes can go anywhere in the project, but the Models folder is used by convention.
The database context is the main class that coordinates Entity Framework functionality for a data model.
public class ContosoPetsContext : DbContext { /*...*/ }
Controllers (HTTP endpoints)
自动生成代码:
-
Marks the class with the ApiController attribute. This attribute indicates that the controller responds to web API requests.
-
Uses DI to inject the database context (
TodoContext
) into the controller. The database context is used in each of the CRUD methods in the controller.
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet tool install -g dotnet-aspnet-codegenerator
dotnet aspnet-codegenerator controller -name TodoItemsController -async -api -m TodoItem -dc TodoContext -outDir Controllers
-m TodoItem -dc TodoContext
:指定了创建的Controller对象关联的数据模型和数据库上下文对象。
Routing and URL Path
[Route("api/[controller]")]
[ApiController]
public class TodoItemsController : ControllerBase{}
Routing to controller actions in ASP.NET Core.
// GET: api/TodoItems/5
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id){}
When
GetTodoItem
is invoked, the value of"{id}"
in the URL is provided to the method in itsid
parameter.
返回值:The return type of the GetTodoItems
and GetTodoItem
methods is ActionResult type. ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message.
POST API处理
从HTTP请求中读取数据。
配置服务
注册服务
Registers the custom DbContext
class
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ContosoPetsContext>(options =>
options.UseInMemoryDatabase("ContosoPets"));
services.AddControllers();
// code omitted for brevity
}
测试
Postman
https://www.postman.com/downloads/
Entity Framework Core
The Microsoft.EntityFrameworkCore.InMemory
package is required to use an EF Core in-memory database.
第三方库
Terminal.GUI
dotnet add package Terminal.GUI
模块
应用实例
Application.Init();
Application.Shutdown ();
视图
应用程序中添加的UI元素组成视图(Views),视图负责处理显示、接收输入事件和参与聚焦机制。
视图可包含任意数量的子视图(Subviews),View.SuperView
是当前视图的容器。
TopLevels
Toplevel
视图占用整个屏幕,不含可见的UI元素,通常需要在程序中向其中添加子视图或组件(如文本标签Label
、菜单MenuBar
、工作窗口Window
等)。
TopLevel top = Application.Top; // 默认的视图
top.add(label);
Application.Run(); // 渲染顶层界面
自定义其他视图:
var top = new Toplevel(){ X=0, Y=0, Width=Dim.Fill(), Height = Dim.Fill() }; Application.Run(top);
Windows
Window
(窗口)视图扩展Toplevel
,将视图划为标题栏和画框(frame),屏幕上可同时存在多个窗口。
Dialogs
Dialog
是位于屏幕中央的一类窗口,以模态方式运行。通过AddButtion
可在底部增加按钮。
bool ok_pressed = false;
var ok = new Button("Ok"){
Clicked = () => { Application.RequestStop (); ok_pressed = true; }
};
var cancel = new Button("Cancel"){
Clicked = () => Application.RequestStop();
};
var dialog = new Dialog("Quit", 60, 7, ok, cancel);
Application.Run(dialog);
if (ok_pressed){
Console.WriteLine ("xxx");
}
布局
UI元素的布局通过指定左上角位置和组件的尺寸确定。布局方案View.LayoutStyle
包括绝对布局和动态布局。
var label2 = new Label (new Rect (1, 2, 20, 1), "World"); // 使用Rect定义绝对尺寸
var label = new Label ("Hello") {
X = 1, //绝对值
Y = Pos.Center(), //动态计算
Width = Dim.Fill(), //动态计算
Height = 1 //绝对值
};
绝对布局
View.Frame
动态布局
位置计算方法:
view.X = Pos.Center () - 10;
view.Y = Pos.Percent (20); //按比例布局
//相对边界布局
view.X = AnchorEnd(10);
//相对其他组件布局
view.X = Pos.X(super_view);
view.Y = Pos.Bottom(another_view);
尺寸计算方法:
view.Width = Dim.Fill () - 10;
view.Height = Dim.Percent(20) - 1;
anotherView.Height = Dim.Height(view)+1;
色彩样式
UI组件
工具栏
窗口
事件处理
Event Processing and the Application Main Loop (gui-cs.github.io)