From 9f1427588332558161cff8a67908e0485a8040b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=96=E5=BF=97=E7=94=9F?= <2756684098@qq.com> Date: Sun, 26 May 2024 21:11:36 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=94=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0240520_NetCore\345\222\214ASP.NetCore.md" | 87 +++++++++++ ...72\347\241\200\344\275\277\347\224\250.md" | 71 +++++++++ ...35\350\265\226\346\263\250\345\205\245.md" | 145 ++++++++++++++++++ .../20240525_API\345\206\231\346\263\225.md" | 70 +++++++++ 4 files changed, 373 insertions(+) create mode 100644 "\350\265\226\345\277\227\347\224\237/20240520_NetCore\345\222\214ASP.NetCore.md" create mode 100644 "\350\265\226\345\277\227\347\224\237/20240521_ASP.NETCore\347\232\204\345\237\272\347\241\200\344\275\277\347\224\250.md" create mode 100644 "\350\265\226\345\277\227\347\224\237/20240523_\344\276\235\350\265\226\346\263\250\345\205\245.md" create mode 100644 "\350\265\226\345\277\227\347\224\237/20240525_API\345\206\231\346\263\225.md" diff --git "a/\350\265\226\345\277\227\347\224\237/20240520_NetCore\345\222\214ASP.NetCore.md" "b/\350\265\226\345\277\227\347\224\237/20240520_NetCore\345\222\214ASP.NetCore.md" new file mode 100644 index 0000000..9c17b6a --- /dev/null +++ "b/\350\265\226\345\277\227\347\224\237/20240520_NetCore\345\222\214ASP.NetCore.md" @@ -0,0 +1,87 @@ +### 一、NET Core简介 +.NET Core是由微软开发的跨平台、开源的开发框架,适用于构建现代、高性能的应用程序 +- 跨平台:.NET Core支持在Windows、macOS和Linux上运行,使得开发者可以在不同的操作系统上进行开发和部署 +- 开源:.NET Core是完全开源的,代码托管在GitHub上。任何人都可以查看、贡献代码并帮助改进该框架 +- 高性能:.NET Core被设计为高性能的,特别适用于需要高吞吐量和低延迟的应用,如微服务和云计算应用 +- 模块化:.NET Core采用模块化设计,开发者可以按需引入所需的库和功能,从而减小应用程序的大小并提高性能 +- CLI工具:.NET Core提供了强大的命令行工具(CLI),支持创建、构建、运行和发布应用程序 +- 统一编程模型:.NET Core提供了一个统一的编程模型,支持多种类型的应用程序,包括控制台应用、Web应用(通过ASP.NET Core)、桌面应用(通过Windows Forms和WPF)、微服务、云服务等 +- 兼容性:.NET Core可以与其他.NET框架(如.NET Framework和Mono)兼容,并且提供了迁移工具,帮助开发者从旧版本迁移到.NET Core。 +- 依赖注入:.NET Core内置依赖注入支持,简化了对象的创建和管理,提升了代码的可测试性和可维护性 +另外一个最常用的.NET平台是.NETFramework,两者是不同的.NET平台,主要的区别是:前者跨平台,后者仅支持Windows +### 二、.NET Standard简介 +.NET Standard是一个旨在提供一组统一API规范的标准,确保不同.NET实现(如 .NET Framework、.NET Core 和 Xamarin)之间的代码兼容性和共享性。具有以下特点: +- 统一API规范 +- 代码共享:开发者可以编写能够在多个.NET平台上运行的库和组件,从而提高代码重用性 +- 版本管理:.NET Standard有多个版本,每个版本包含一组特定的API +- 跨平台支持 +### 三、ASP.NET Core简介 +ASP.NET Core是一个开源、跨平台的高性能Web框架,用于构建现代、云端优化的Web应用和服务。具有以下特点: +- 跨平台 +- 开源 +- 高性能 +- 模块化和灵活性:采用模块化设计,开发者可以根据需要选择和配置中间件组件,构建高度定制化的请求处理管道- 统一的编程模型 +- 依赖注入:内置了依赖注入(DI)框架,简化了应用的配置和管理,提高了代码的可维护性和可测试性 +- 现代开发工具 +- 云优化 +- 兼容性和迁移 +### 四、设置开发环境 +使用.NETCoreCLI可以创建一个.NETCore应用 +~~~js +dotnet new console -o HelloConsole +dotnet new api -o HelloApi +dotnet new classlib -o HelloClassLibrary +// -o 表示要创建的位置 +~~~ +除此之外,.NETCoreCLI还有其他命令: + +### 五、创建第一个API项目 +~~~js +// 恢复项目中的NuGet包依赖项: +dotnet restore + +// 编译项目: +dotnet build + +// 运行项目: +dotnet run + +// 测试项目: +dotnet test + +// 发布项目: +dotnet publish -c Release -o +-c Release指定发布配置为Release模式,-o指定输出文件夹 + +// 添加包: +dotnet add package + +// 添加项目引用: +dotnet add reference + +// 移除引用: +dotnet remove + +// 清理项目: +dotnet clean +~~~ +### 六、创建第一个API项目 +#### 1.使用vsCode +在终端输入命令创建API项目 +~~~js +dotnet new webapi -n HelloApi +~~~ +#### 2.使用VisualStudio +1. 选择“ 文件 ”→“ 新建 ”→“ 项目 ” +2. 在弹出的新建项目对话框中选择左侧的“VisualC#”,继续选择“.NET Core”;在右侧选择“ASP.NET Core Web应用程序”,输入新项目名称 +3. 选择“API”模板,并且选择“不进行身份验证” +#### 3.运行项目 +使用命令【dotnet run】运行项目后,打开浏览器会返回404,需要将/weatherforecast添加到URL中,就会返回示例JSON代码 +### 七、关于Swagger +将/swagger附加到URL中就会显示Swagger页面,该页面会显示: +- 用于测试 WeatherForecast API 的 Curl 命令 +- 用于测试 WeatherForecast API 的 URL +- 响应代码、正文和标头 +- 包含媒体类型、示例值和架构的下拉列表框 +Swagger 用于为 Web API 生成有用的文档和帮助页面 + diff --git "a/\350\265\226\345\277\227\347\224\237/20240521_ASP.NETCore\347\232\204\345\237\272\347\241\200\344\275\277\347\224\250.md" "b/\350\265\226\345\277\227\347\224\237/20240521_ASP.NETCore\347\232\204\345\237\272\347\241\200\344\275\277\347\224\250.md" new file mode 100644 index 0000000..5868614 --- /dev/null +++ "b/\350\265\226\345\277\227\347\224\237/20240521_ASP.NETCore\347\232\204\345\237\272\347\241\200\344\275\277\347\224\250.md" @@ -0,0 +1,71 @@ +### 一、解决方案和项目之间的关系 +1. 编译或打包解决方案时,会同时编译或打包其下所有项目 +2. 如果运行解决方案,会按编排的(指定的启动项目),分别编译该项目 +3. 在根目录下编译项目会一起编译解决方案,而在项目目录下编译却只会编译该项目 + +### 二、在项目中引用另一个项目 +~~~js +dotnet add.\MyApi\ reference .\ApiDemo\ +// 在MyApi项目中引用ApiDemo项目 +// 则在MyApi.csproj文件中会出现以下代码 + + + +~~~ + +### 三、添加依赖包 +~~~js +dotnet add .\MyApi\ package package_name +// 则在MyApi.csproj文件中会出现以下代码: + + +// 也可以根据MyApi.csproj文件还原包 +dotnet restore +~~~ + +### 四、编译一个简单的api请求 +1. 编译代码 +~~~js +// 在program.cs中 +// 使用了 MapGet 方法来指定了一个 GET 请求的路由路径为 "/api/users" +app.MapGet("/api/users",()=>{ + // 创建了一个 List 类型的列表对象,用于存储动态类型的元素 + var list = new List(); + list.Add(new{ + Id=1, + Username="猪猪侠", + Password="123", + Skill="变身" + }); + list.Add(new{ + Id=2, + Username="小呆呆", + Password="123", + Skill="流鼻涕" + }); + return list; +}); +~~~ +2. 启动项目 +~~~js +// 在根目录启动命令: +dotnet run --project .\MyApi\ +// 也可以直接在项目目录启动: +dotnet run project +// 监控修改(热重载):无需每次修改后do重新运行 +dotnet watch project +~~~ +### 五、中间件 +1. 添加中间件 +~~~js +// 接受 HttpContext 对象 ctx 和一个 next 委托作为参数 +app.Use(async (ctx,next)=>{ + // 创建变量forecast,其中存储包含1到10的整数序列 + // Enumerable.Range 方法用于生成指定范围内的整数序列 + var forecast = Enumerable.Range(1,10); + // 调用下一个中间件或终结点,使得控制权传递给下一个中间件或请求处理终结点 + await next(); + // 调用下一个中间件或终结点,使得控制权传递给下一个中间件或请求处理终结点 + ctx.Response.WriteAsync("C929星球"); +}); +~~~ \ No newline at end of file diff --git "a/\350\265\226\345\277\227\347\224\237/20240523_\344\276\235\350\265\226\346\263\250\345\205\245.md" "b/\350\265\226\345\277\227\347\224\237/20240523_\344\276\235\350\265\226\346\263\250\345\205\245.md" new file mode 100644 index 0000000..ae2f1f7 --- /dev/null +++ "b/\350\265\226\345\277\227\347\224\237/20240523_\344\276\235\350\265\226\346\263\250\345\205\245.md" @@ -0,0 +1,145 @@ +### 一、依赖注入 + +#### 1.简介 + +- 组件与组件之间存在依赖关系,但是但一方不存在时,另一方就不能正常工作,这个时候就需要采用控制反转。 +- 控制反转是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度,其中最常见的方式叫做依赖注入,也可以说依赖注入和控制反转是一回事 +- 依赖注入的方式主要有三种: + - 构造函数注入 + - 属性注入:通过在需要注入的类中声明属性 + - 方法注入:将依赖项通过方法参数传递的方式进行依赖注入 + +#### 2.举例说明 + +``` + // MyDependency.cs + public class MyDependency + { + public void WriteMessage(string message) + { + Console.WriteLine($"调用的数据为{message}"); + } + } + + // IndexModel.cs + public class IndexModel + { + // 假设在当前类中需要引用MyDependency类的实例 + private readonly MyDependency _dependency; + public IndexModel(){ + // 创建一个MyDependency实例 + // MyDependency是一个依赖项,为IndexModel提供数据 + _dependency = new MyDependency(); + } + public void DoSomething() + { + _dependency.WriteMessage("超级侦探"); + } + } + + //Program.cs + public static void Main(string[] args) + { + // 调用 CreateWebHostBuilder 方法来创建一个 IWebHostBuilder 实例 + var app = CreateWebHostBuilder(args).Build(); + // 在这里实例化 IndexModel 并调用方法进行测试 + var indexModel = new IndexModel(); + indexModel.DoSomething(); + // 运行应用程序 + app.Run(); //控制台输出:调用的数据为超级侦探 + } +``` + +从上面可知: + +- 想要替换 MyDependency的结果,必须修改 IndexModel 类 +- 很难进行单元测试 +- 如果 MyDependency 具有依赖项,则必须由 IndexModel 类对其进行配置 依赖关系注入通过以下方式解决这些问题: +- 使用接口或基类将依赖关系实现抽象化 +- 在服务容器中注册依赖关系。 ASP.NET Core 提供了一个内置的服务容器 IServiceProvider。 服务通常已在应用的 Program.cs 文件中注册 +- 将服务注入到使用它的类的构造函数中。 框架负责创建依赖关系的实例,并在不再需要时将其释放 + +``` + // 下面是构造函数注入 + // MyDependency.cs + // IMyDependency 接口 + public interface IMyDependency + { + // 定义了一个方法 WriteMessage(string message)用于写入消息 + void WriteMessage(string message); + } + // MyDependency 类实现了 IMyDependency 接口 + // 提供了 WriteMessage 方法的具体实现 + public class MyDependency : IMyDependency + { + public void WriteMessage(string message) + { + Console.WriteLine($"调用的数据为{message}"); + } + } + + // IndexModel.cs + public class IndexModel + { + // 构造_idependency属性,并在构造函数中注入(属性注入) + private readonly IMyDependency _idependency; + // 使用构造函数注入的方式来将 IMyDependency 的具体实现注入到 IndexModel 中 + public IndexModel(IMyDependency dependency){ + // 控制反转,不需要直接new实例化 + _idependency = dependency; + } + public void DoSomething() + { + _idependency.WriteMessage("超级侦探"); + } + } + + // Startup.cs + // 启动类,包含应用程序的配置信息 + public class Startup + { + public void Configure(IApplicationBuilder app) + { + // ...... + } + public void ConfigureServices(IServiceCollection services) + { + // 将 MyDependency 类注册为单例服务 + // 注册 将IMyDependency实现类MyDependency实例化一个,放入容器 + services.AddSingleton(); + // 将 IndexModel 类注册为作用域服务 + services.AddScoped(); + } + } + + // program.cs + public static void Main(string[] args) + { + var app = CreateWebHostBuilder(args).Build(); + // 在 using 语句中创建作用域,以便在作用域内获取服务 + using (var scope = app.Services.CreateScope()) + { + // 获取服务提供者 services + var services = scope.ServiceProvider; + // 从服务提供者中获取 IndexModel 的实例 + var indexModel = services.GetService(); + indexModel.DoSomething(); //控制台输出 调用的数据为超级侦探 + } + app.Run(); + } +``` + +#### 3.依赖注入容器 + +- 专门的类用来负责管理创建所需要的类,并创建它所有可能要用到的依赖,这个类就是依赖注入容器,也可以称之为控制反转容器(IoC容器) +- 可以把依赖注入容器看作一个用于创建对象的工厂,它负责向外提供被请求要创建的对象,当创建这个对象时,如果它又依赖了其他对象或者服务,那么容器会负责在其内部查找需要的依赖,并创建这些依赖,直至所有依赖项都创建完成后,最终返回被请求的对象 +- 容器也负责管理所创建对象的生命周期 + +### 二、ASP.NET Core中的依赖注入 + +1. ASP.NET Core框架内部集成了自身的依赖注入容器 +2. 所有被放入依赖注入容器的类型或组件称为服务,添加服务就使用Startup类的ConfigureServices方法 +3. 服务的生命周期有以下三种: + - Singleton:容器会创建并共享服务的单例,且一直存在于应用程序的整个生命周期里 + - TRansient:每次请求,总会创建新实例 + - Scope:在每次请求时会创建服务的新实例,并在这个请求内一直共享这个实例 \ No newline at end of file diff --git "a/\350\265\226\345\277\227\347\224\237/20240525_API\345\206\231\346\263\225.md" "b/\350\265\226\345\277\227\347\224\237/20240525_API\345\206\231\346\263\225.md" new file mode 100644 index 0000000..bc1507f --- /dev/null +++ "b/\350\265\226\345\277\227\347\224\237/20240525_API\345\206\231\346\263\225.md" @@ -0,0 +1,70 @@ +1. 入口程序 +~~~c# + using Microsoft.AspNetCore; + // 1. 命名空间声明 + namespace Api + { + // 2. 类声明 + // Program类是应用程序的入口点,应用程序通常从Main方法开始执行 + public class Program + { + public static void Main(string[] args) + { + CreateWebHostBuilder(args).Build().Run(); + // CreateWebHostBuilder(args)方法被调用来创建一个IWebHostBuilder对象 + // Build()方法被调用在IWebHostBuilder对象上,生成一个IWebHost对象 + // Run()方法启动Web主机,使应用程序开始监听Web请求 + } + public static IWebHostBuilder CreateWebHostBuilder(string[] args) + { + return WebHost.CreateDefaultBuilder(args).UseStartup(); + // CreateWebHostBuilder方法用于配置和创建一个Web主机生成器 + // UseStartup()方法指定Startup类作为应用程序的启动类 + } + } + } +~~~ +2. 启动类 +~~~c# + // Startup类是ASP.NET Core应用程序启动时调用的类,用于配置应用程序服务和HTTP请求管道 + public class Startup + { + // 用于添加和注册中间件 + public void Configure(IApplicationBuilder app) + { + app.UseRouting(); //添加路由中间件 + // 配置终结点路由 + app.UseEndpoints(endpoints => { + endpoints.MapControllers(); + // 添加控制器终结点到请求管道中,这使得控制器能够处理HTTP请求 + }); + } + // 注册准备依赖注入的服务 + // ConfigureServices方法用于配置依赖注入容器,添加应用程序所需的服务 + public void ConfigureServices(IServiceCollection services) + { + services.AddControllers(); //添加MVC控制器相关的服务到依赖注入容器中 + } + } +~~~ +3. 控制器 +~~~c# + namespace Api.Controllers; + + [Route("[controller]")] //定义控制器的路由前缀,即/blogs + // BlogsController类继承自ControllerBase,它是一个用于构建API的基类(不包含视图支持) + public class BlogsController : ControllerBase + { + // 处理对/blogs的GET请求 + public IActionResult Index(){ + return Ok("999"); //返回一个包含字符串"999"的200 OK响应 + } + + [Route("{id}")] //定义Single方法的路由模板 + // 处理对/blogs/{id}的GET请求,接受一个整型参数id + public IActionResult Single(int id) + { + return Ok(id); //返回一个包含id值的200 OK响应 + } + } +~~~ \ No newline at end of file -- Gitee