From 89c10852302e2b244762ec41d29eedc573ff1aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=A9=89=E5=A9=B7?= <1029854305@qq.com> Date: Mon, 20 May 2024 16:59:10 +0800 Subject: [PATCH 1/2] . --- ...20\345\210\233\345\273\272api\351\241\271\347\233\256.md" | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 "\347\231\275\345\251\211\345\251\267/20240520\345\210\233\345\273\272api\351\241\271\347\233\256.md" diff --git "a/\347\231\275\345\251\211\345\251\267/20240520\345\210\233\345\273\272api\351\241\271\347\233\256.md" "b/\347\231\275\345\251\211\345\251\267/20240520\345\210\233\345\273\272api\351\241\271\347\233\256.md" new file mode 100644 index 0000000..6a65d5d --- /dev/null +++ "b/\347\231\275\345\251\211\345\251\267/20240520\345\210\233\345\273\272api\351\241\271\347\233\256.md" @@ -0,0 +1,5 @@ +## .NET Core和ASP.NET Core + +## 创建 +1. dotnet new webapi -n (项目名称) +2. dotnet run //运行 \ No newline at end of file -- Gitee From 8f6a4ca38ad8b775060f68041773c8ffaee5ac88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=A9=89=E5=A9=B7?= <1029854305@qq.com> Date: Sun, 26 May 2024 22:38:47 +0800 Subject: [PATCH 2/2] 1 --- ...345\273\272api\351\241\271\347\233\256.md" | 8 +- ...\273\266MepGet\346\226\271\346\263\225.md" | 78 ++++++++++ .../20240523.md" | 143 ++++++++++++++++++ .../20240524.md" | 70 +++++++++ 4 files changed, 297 insertions(+), 2 deletions(-) create mode 100644 "\347\231\275\345\251\211\345\251\267/20240521\344\270\255\351\227\264\344\273\266MepGet\346\226\271\346\263\225.md" create mode 100644 "\347\231\275\345\251\211\345\251\267/20240523.md" create mode 100644 "\347\231\275\345\251\211\345\251\267/20240524.md" diff --git "a/\347\231\275\345\251\211\345\251\267/20240520\345\210\233\345\273\272api\351\241\271\347\233\256.md" "b/\347\231\275\345\251\211\345\251\267/20240520\345\210\233\345\273\272api\351\241\271\347\233\256.md" index 6a65d5d..2ad12c3 100644 --- "a/\347\231\275\345\251\211\345\251\267/20240520\345\210\233\345\273\272api\351\241\271\347\233\256.md" +++ "b/\347\231\275\345\251\211\345\251\267/20240520\345\210\233\345\273\272api\351\241\271\347\233\256.md" @@ -1,5 +1,9 @@ ## .NET Core和ASP.NET Core ## 创建 -1. dotnet new webapi -n (项目名称) -2. dotnet run //运行 \ No newline at end of file +1. dotnet new webapi -n //(创建API项目) +2. dotnet new classlib -n /(创建类库) +3. dotnet new sln -n //(创建解决方案) +4. dotnet sln add name/NAME //(把添加入解决方案) +5. dotnet bulid //(编译) +6. dotnet run //运行 \ No newline at end of file diff --git "a/\347\231\275\345\251\211\345\251\267/20240521\344\270\255\351\227\264\344\273\266MepGet\346\226\271\346\263\225.md" "b/\347\231\275\345\251\211\345\251\267/20240521\344\270\255\351\227\264\344\273\266MepGet\346\226\271\346\263\225.md" new file mode 100644 index 0000000..c02a7a6 --- /dev/null +++ "b/\347\231\275\345\251\211\345\251\267/20240521\344\270\255\351\227\264\344\273\266MepGet\346\226\271\346\263\225.md" @@ -0,0 +1,78 @@ +## 创建项目 添加解决方案 + dotnet new webapi -n name1 创建项目 + dotnet new classlib -n name2 创建类库 + dotnet new sln -n name 创建解决方案 + dotnet sln add .\name1 添加进解决方案 + dotnet sln add .\name2 添加进解决方案 + dotnet build编译 + 在解决方案的目录中运行,都打包 + 在项目中运行,直达包当前的项目 + dotnet add .\demo-one\ reference .\demo-two\ 在demo-one中添加demo-two + dotnet add .\demo-one package Microsoft.EntityFrameworkCore 添加依赖包 + dotnet restore 还原依赖包 通常不会单独使用 + dotnet build 也可还原依赖包 + +## 把mini api改为传统控制器的方式 + +## 运行 + dotnet run --project .\ccc\demo-one + +## 监控 热重载 + dotnet watch --project .\ccc\demo-one + +## 清理缓存 + dotnet clean .\ccc\demo-one + +## 中间件 异步函数 + 先执行后面那个 + app.Use(async (ctx, next) => + { + var forrecast = Enumerable.Range(1,10); + await next(); + await ctx.Response.WriteAsync("hello"); + }); + +## MapGet + var builder = WebApplication.CreateBuilder(args); + + var app = builder.Build(); + + app.MapGet("/",async ctx => { + + await ctx.Response.WriteAsync("8888"); + }); + //测试 + app.MapGet("/leaf",async ctx => { + + await ctx.Response.WriteAsync("9999"); + }); + //测试 与上区别为路径不同 + app.Run(); + +## 测试 + 在.http文件中 + @url=http://localhost:3000 + GET {{url}}/api/users HTTP/1.1 + +## 运行重点 +1. 重新运行 +2. 清理缓存 + +# 作业练习 + +1. 在最简单的形式下,转换为在单独的文件中写路径-抽离 +2. 在最简形式下,转换为原来传统的控制器的模式-转换 + +var builder = WebApplication.CreateBuilder(args); + +var app = builder.Build(); + +app.MapGet("/",async ctx => { + + await ctx.Response.WriteAsync("8888"); +}); +app.MapGet("/leaf",async ctx => { + + await ctx.Response.WriteAsync("9999"); +}); +app.Run(); \ No newline at end of file diff --git "a/\347\231\275\345\251\211\345\251\267/20240523.md" "b/\347\231\275\345\251\211\345\251\267/20240523.md" new file mode 100644 index 0000000..6ecd2fa --- /dev/null +++ "b/\347\231\275\345\251\211\345\251\267/20240523.md" @@ -0,0 +1,143 @@ +### 一、将简单的api转换为控制器模式的写法(Api写法) +1. program.cs部分代码 +![pro-2024-5-2322:17:56.png](https://gitee.com/huangxuefang0929/xiu_img/raw/master/pro-2024-5-2322:17:56.png) +2. Startup.cs部分代码 +![startup-2024-5-2322:17:48.png](https://gitee.com/huangxuefang0929/xiu_img/raw/master/startup-2024-5-2322:17:48.png) +3. HelloController.cs代码不变 + +### 二、依赖注入 +#### 1.简介 +- 组件与组件之间存在依赖关系,但是但一方不存在时,另一方就不能正常工作,这个时候就需要采用控制反转。 +- 控制反转是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度,其中最常见的方式叫做依赖注入,也可以说依赖注入和控制反转是一回事 +- 依赖注入的方式主要有三种: + - 构造函数注入 + - 属性注入:通过在需要注入的类中声明属性 + - 方法注入:将依赖项通过方法参数传递的方式进行依赖注入 +#### 2.举例说明 +~~~js + // 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 文件中注册 +- 将服务注入到使用它的类的构造函数中。 框架负责创建依赖关系的实例,并在不再需要时将其释放 +~~~js + // 下面是构造函数注入 + // 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/\347\231\275\345\251\211\345\251\267/20240524.md" "b/\347\231\275\345\251\211\345\251\267/20240524.md" new file mode 100644 index 0000000..bc1507f --- /dev/null +++ "b/\347\231\275\345\251\211\345\251\267/20240524.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