我是靠谱客的博主 细心茉莉,最近开发中收集的这篇文章主要介绍ASP.NET Core 3.x 学习笔记(1)——从项目结构了解依赖注入、管道、路由ASP.NET Core 3.x 学习笔记(1)——从项目结构了解依赖注入、管道、路由,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

ASP.NET Core 3.x 学习笔记(1)——从项目结构了解依赖注入、管道、路由

  • ASP.NET Core 3.x 学习笔记(1)——从项目结构了解依赖注入、管道、路由
    • 项目结构
      • Program.cs
      • Startup.cs
      • 在 ASP.NET Core MVC 中简单实现
      • 项目启动
      • 环境变量
      • 静态文件
      • 包管理
        • 静态文件合并
    • 依赖注入 DI(Dependency Injection)
      • DI 的优点
    • ASP.NET Core 管道(pipeline)
      • 配置中间件
    • 路由
      • ASP.NET Core 应用的多样性
      • 端点 endpoint

本系列学习笔记均来源于B站UP主”软件工艺师“的学习视频,学习连接如下:

https://www.bilibili.com/video/BV1c441167KQ

ASP.NET Core 3.x 学习笔记(1)——从项目结构了解依赖注入、管道、路由

项目结构

创建一个 Empty 的 .NET Core 3.0 web 项目后,会生成如下结构的项目代码。

在这里插入图片描述

Program.cs

namespace ASPNETCore_Learning_Three
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

ASP.NET Core 应用本质上还是控制台应用,所以上面的 Main 方法还是和控制台应用的 Main 方法是一个概念。

ASP.NET Core 整个应用的配置是通过代码中的 CreateHostBuilder 方法来进行的。

在 Main 方法中调用 CreateHostBuilder(args).Build() 之后,程序从控制台应用变成了 ASP.NET Core 应用。

ConfigureWebHostDefaults 方法进行一些默认配置。

Startup.cs

namespace ASPNETCore_Learning_Three
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            //负责配置依赖注入相关的东西
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }
}

Startup.cs 也是用于 ASP.NET Core 项目的配置,配置过程相对比较动态。而 Program.cs 则相对比较死板。

运行时通过约定对 ConfigureServices 和 Configure 方法进行调用。调用顺序是,先 ConfigureServices 后 Configure。

ConfigureServices 方法主要负责配置依赖注入相关的东西。

Configure 承担 ASP.NET Core 管道路由的作用;

在 ASP.NET Core MVC 中简单实现

继续在上面项目结构的代码中,创建对应的 Services 和 Controllers。

在这里插入图片描述

其中,Services文件夹中 IClock 为一个 interface;ChinaClock 和 UtcClock 类实现 IClock 接口。HomeController 类实现 Microsoft.AspNetCore.Mvc 的 Controller 接口。

HomeController.cs

using ASPNETCore_Learning_Three.Services;
using Microsoft.AspNetCore.Mvc;

namespace ASPNETCore_Learning_Three.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// 依赖注入。通过构造函数注入了一个实现了IClock接口的实例。
        /// 因为Startup.cs中的services.AddSingleton<IClock, ChinaClock>(); 
        /// 此处注入的即是 ChinaClock
        /// </summary>
        /// <param name="clock"></param>
        public HomeController(IClock clock) 
        {

        }
    }
}

Startup.cs

using ASPNETCore_Learning_Three.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace ASPNETCore_Learning_Three
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            //负责配置依赖注入相关的东西

            services.AddControllersWithViews();  //使用 MVC 相关功能
            //services.AddControllers();  //做 API 使用这个就可以
            //services.AddMvc();  //这个有特别多完整的功能,此处不需要

            services.AddSingleton<IClock, ChinaClock>(); //每当有一个类型请求了一个IClock服务,IoC容器则返回一个ChinaClock实例
            //尽量使用 接口(IClock)的形式,使用接口可以使 Controller 与具体的服务类(ChinaClock、UtcClock)之间解耦
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }
}

如上代码:

  • services.AddControllersWithViews():使用 MVC 相关功能
  • services.AddSingleton<IClock, ChinaClock>()
    • 每当有一个类型请求了一个IClock服务,IoC容器则返回一个ChinaClock实例
    • 尽量使用接口(IClock)的形式,使用接口可以使 Controller 与具体的服务类(ChinaClock、UtcClock)之间解耦
  • public HomeController(IClock clock) :通过构造函数注入了一个实现了IClock接口的实例(依赖注入)
    • 因为 Startup.cs 中的services.AddSingleton<IClock, ChinaClock>();此处注入的即是 ChinaClock。

项目启动

APS.NET Core Web 程序有两种启动方式,如下图:

在这里插入图片描述

  • 一种是通过 IIS 来启动
  • 一种是 APS.NET Core 自己运行。因为 APS.NET Core 本身是一个控制台应用,所以可以自己运行。而且 APS.NET Core 控制台应用里面内嵌了一个小巧的 web 服务器:Kestrel。

配置项目调试环境:

在项目的 ”属性“ => ”调试“ 选项中,可以配置项目启动时的调试环境。也可在项目路径下的 “Properties” 文件夹中的 “launchSettings.json” 进行更改。

在这里插入图片描述

环境变量

如上“项目启动”中的图片,可以通过项目环境变量 APSNETCORE_ENVIRONMENT 的值来判断当前是某个环境。

APSNETCORE_ENVIRONMENT 有三个内置的值,分布可以通过三个默认方法获取:

  • env.IsDevelopment():表示当前为”Development“,开发环境。

  • env.IsProduction():表示当前为”Production“,生产环境。

  • env.IsStaging():示当前为”Staging“,生产环境。

也可以自定义环境,比如可以将 APSNETCORE_ENVIRONMENT 的值设置为 ”OK“,则可以通过如下方法获取:

  • env.IsEnvironment(“OK”);

如上环境变量也都是在 Configure 方法中配置,如下:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //env.IsProduction(); env.IsStaging(); env.IsDevelopment()  //是三种内置的环境变量
    //env.IsEnvironment("OK");  //也可以自定义环境变量,然后通过 env.IsEnvironment() 获得
    if (env.IsDevelopment()) //判断当前是否为 开发模式
    {
        app.UseDeveloperExceptionPage(); //异常页中间件:展示当前程序没有处理和捕获的异常的详细信息到某个固定页面
    }

}

ASP.NET Core 也可以针对不同的环境有不同的配置方法,比如可以对 Development 单独有一个 Configure 方法。如下,重新定义一个方法,方法名为在 Configure 后面加上 环境变量即可,如下:

public void ConfigureDevelopment(IApplicationBuilder app, IWebHostEnvironment env)
{ 
}

如此之后,若当前环境为 Development,则调用 ConfigureDevelopment 方法,否则调用 Configure 方法。

同理,对于其它环境变量,如 Production,或 ConfigureServices 方法均可以如此处理。

Startup.cs 类也可以针对不同环境设置不同方法,如 Development 环境下可使用 StartupDevelopment 类。若不同环境下使用不同的 Startup 类,则 Program.cs 中 CreateHostBuilder 方法需要做如下更改,以便获得正确的 Startup 类

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
                              {
                                  //webBuilder.UseStartup<Startup>();
                                  webBuilder.UseStartup((typeof(Program)));
                              });

静态文件

在 ASP.NET Core Web 应用程序中,静态文件(css/html/images)应该放在 wwwroot 文件夹下。

在这里插入图片描述

包管理

  • 服务器端(后端):Nuget
  • 前端:npm

前端包管理:

Visual Studio 中可以直接新建 npm 配置文件(package.json),在 ”添加项“ 中直接搜索 ”npm“ 即可。添加后生成 package.json 文件,可同正常 node 项目一样,在 package.json 中配置依赖性,然后通过 npm 安装。

也可使用 Visual Studio 自带的管理工具。选中项目,右键“添加”,选择“客户端库”

在这里插入图片描述

静态文件合并

Visual Studio 2019 中 ASP.NET Core 支持将静态文件,如 css 文件,合并并压缩到一个文件中;也可以移动 css 文件所在位置。

如下示例,在项目中有 bootstrap.css 和 site.css 两个 css 文件,现在需要将两个文件合并并且压缩空格。

在这里插入图片描述

在项目中新建 bundleconfig.json 文件,文件中代码如下:

[
  {
    //合并代码
    "outputFileName": "wwwroot/css/all.min.css",
    "inputFiles": [
      "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
      "wwwroot/css/site.css"
    ]
  },
  {
    //移动bootstrap.css文件,并压缩代码中的空格
    "outputFileName": "wwwroot/css/bootstrap.css",
    "inputFiles": [
      "wwwroot/lib/bootstrap/dist/css/bootstrap.css"
    ],
    "minify": {
      "enabled": true
    }
  }
]

代码分别表示:

  • 合并 css 文件到 “wwwroot/css/all.min.css”
  • 移动bootstrap.css文件,并压缩代码中的空格

然后通过 Nuget 安装 BuildBundlerMinifier 到项目。安装好后重新生成项目,即可看见合并后的结果。

在这里插入图片描述

若需要具体了解 Bundle,可在 MSDN 查看,如下图。

在这里插入图片描述

依赖注入 DI(Dependency Injection)

依赖注入的机制依赖于 IoC 容器(Inversion of Control 控制反转)

依赖注入典型原理的应用:ASP.NET Core Web 应用启动时

  • 在 IoC 容器中注册服务(即某些类或类型)
  • 其它类或类型可以向 IoC 容器请求注册的服务的实例
  • 在注册的时候可以设置这些服务实例的生命周期(服务实例的生命周期是 IoC 容器来控制的)

生命周期

  • Transient:注册的服务在每次被请求的时候都会生成一个新的实例;
  • Scoped:ASP.NET Core Web 中,每一次 Web 请求则生成一个实例;当 Web 请求被处理完成时,生命周期截至;
  • Singleton:服务实例一旦被创建,之后每次请求这个服务的时候,都使用这个实例;实例会一致存活到应用程序停止;

DI 的优点

  • 解耦,使 Controller 和 Service 之间没有强依赖,而是都依赖于一个抽象的接口(如上文中的 HomeController 和 ChianClock 之间依赖于 IClock)
    • 利于单元测试(另外了解单元测试)
  • 不需要了解具体的服务类(内部结构、细节之类的)
  • 不需要管理服务类的生命周期(由 IoC 容器控制)

ASP.NET Core 管道(pipeline)

在上文项目结构中提到的 Startup.cs 类中的 Configure 方法配置了 ASP.NET Core 针对处理 http 请求的管道。(后续了解 ASP.NET Core 源码,管道是如何配置的)

IApplicationBuilder 在 ASP.NET Core 源码(在 Program.cs)中就已经完成配置,此处可以直接对其进行依赖注入操作即可。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //......
}

管道对浏览器的 http 请求如何响应?

ASP.NET Core 应用程序从浏览器接收到 http 请求:请求从管道进入,处理完后从管道返回;具体的处理过程在管道中发生,若想要对请求进行处理响应,则需要在管道中添加相应的中间件

如下图,http 请求从浏览器进入 ASP.NET Core 管道,在管道中经过身份验证中间件(Auth)、MVC中间件、静态文件处理中间件(Static Files)后对具体的数据进行处理。

在这里插入图片描述

配置中间件

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 {
     if (env.IsDevelopment()) //判断当前是否为 开发模式
     {
         app.UseDeveloperExceptionPage(); //中间件:展示当前程序没有处理和捕获的异常的详细信息到某个固定页面
     }

     app.UseStaticFiles();  //静态文件中间件,添加后可以使用 js,html,css 等静态文件。该中间件放在路由中间件前面即可。

     app.UseHttpMethodOverride();  //可以将 http 请求转化为 https 请求。

     app.UseAuthentication();  //身份验证的中间件。该中间件必须放在 UseEndpoints 之前

     app.UseRouting();  //路由中间件:

     app.UseEndpoints(endpoints =>
                      {
                          endpoints.MapGet("/", async context =>
                          {
                              await context.Response.WriteAsync("Hello World!");
                          });
                      });
 }

如上 Startup.cs 类中的 Configure 方法代码,添加了如下中间件:

  • UseDeveloperExceptionPage():展示当前程序没有处理和捕获的异常的详细信息到某个固定页面
  • UseStaticFiles():静态文件中间件,添加后可以使用 js,html,css 等静态文件。该中间件放在路由中间件前面即可。
  • UseHttpMethodOverride():可以将 http 请求转化为 https 请求。
  • UseAuthentication():身份验证的中间件。该中间件必须放在 UseEndpoints 之前
  • UseRouting():路由中间件
  • UseEndpoints:端点中间件。

中间件注册的先后顺序非常重要:如上文中 UseAuthentication 中间件必须放在 UseEndpoints 之前,因为很多情况下,端点的请求在处理之前需要对身份进行验证。

路由

路由是 Startup.cs 类中的 Configure 方法另一个重要的作用。

在 ASP.NET Core 3.0 之前,路由中间件(UseRouting())是作为 MVC 中间件的一部分存在的。在 3.0 版本之后将 路由中间件单独提取出来,这样就可以配合其它中间件一起使用。

为什么把 路由中间件单独提取出来?见下文“ASP.NET Core 应用的多样性”

在这里插入图片描述

路由中间件(UseRouting())检查在应用中已经注册的端点(见下文),这个端点可能是 MVC 注册的,也可能是 SignalR 注册的,抑或是其它;

路由中间件判断进入管道的 http 请求是在哪个端点上出现的(这是个重要的信息),并传递给后续的中间件,后续的中间件就可以知道端点的信息(如端点是谁注册的)

**端点中间件(UseEndpoints())**可以注册端点,当请求到达 UseEndpoints(),请求就可以被响应的端点进行处理

ASP.NET Core 应用的多样性

ASP.NET Core 应用存在多种技术,如下三种技术,都需要路由,故将路由中间件提取出来。

  • MVC:/Home/Index
  • Razor Pages:/SomePage
  • SignalR:/Hub/Chat

端点 endpoint

端点指的是进入管道的 http 请求的 url 的结尾那部分,这部分会被中间件进行处理。

  • /{controller}/{action}
  • /home/index

在 MVC 中,如果想处理端点,就需要指定路由。指定路由有两种方式

  1. 在 Controller 上写一些 Attribute:Attribute 路由(MVC 5)
  2. 指定一个路由表,表中设定的路由其实就是一些模板,这些模板会尝试匹配一些特定的 url 端点,

在 MVC 项目中,可将上述 Configure 方法中的端点中间件(UseEndpoints)中间的路由配置改成如下形式:
如下代码设置默认路由为 Home/Index

app.UseEndpoints(endpoints =>
                 {
                     //使用 MVC 可以将上述代码改成如下形式
                     //controller 默认状为 Home;action 默认值为 Index;id 可选
                     endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");  //路由表中添加一个路由方法

                     //当使用 Attribute 路由时,使用如下方法即可
                     //endpoints.MapControllers();
                 });

最后

以上就是细心茉莉为你收集整理的ASP.NET Core 3.x 学习笔记(1)——从项目结构了解依赖注入、管道、路由ASP.NET Core 3.x 学习笔记(1)——从项目结构了解依赖注入、管道、路由的全部内容,希望文章能够帮你解决ASP.NET Core 3.x 学习笔记(1)——从项目结构了解依赖注入、管道、路由ASP.NET Core 3.x 学习笔记(1)——从项目结构了解依赖注入、管道、路由所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部