# ASP.NET Core基础

## 托管设置

&#x20;设置项目文件的`AspNetCoreHostingModel`属性

```
<PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <!--<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>-->
    <AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
  </PropertyGroup>
```

* InProcess：使用IIS服务器托管
* OutOfProcess：使用自带Kestrel服务器托管（自宿主）

## 配置源

* `appsettings.json`，`appsettings.{xxxxx}.json` 不同环境下对应不同的托管环境
* User secrets (用户机密)
* Environment variables (环境变量)
* Command-line argument (命令行参数) `donnet run MyKey="xxxxxx"` Tips：它们的关系是依次加载，逐层覆盖

## 中间件

* 可同时被访问和请求
* 可以处理请求后，然后将请求传递给下一个中间件
* 可以处理请求后，并使管道短路
* 可以处理传出响应
* 中间件是按照添加的顺序执行的

**通过在Configure中添加参数ILogger\<Startup> logger引入ASP.Net Core自带的日志组件。**

```
public void Configure(IApplicationBuilder app, IWebHostEnvironment env,ILogger<Startup> logger)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.Use(async (context, next) =>
            {
                context.Response.ContentType = "text/plain;charset=utf-8";

                logger.LogInformation("M1：传入请求");
                await next();
                logger.LogInformation("M1：传出响应");
            });

            app.Use(async (context, next) =>
            {
                context.Response.ContentType = "text/plain;charset=utf-8";

                logger.LogInformation("M2：传入请求");
                await next();
                logger.LogInformation("M2：传出响应");
            });

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("M3：处理请求，并生成响应");

                logger.LogInformation("M3：处理请求，并生成响应");
            });
        }
```

**输出日志：（可以看到三个中间件的执行过程）**

```
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/2.0 GET https://localhost:44383/  
StudyManagement.Startup:Debug: M1: 传入请求
StudyManagement.Startup:Debug: M2: 传入请求
StudyManagement.Startup:Debug: M3: 处理请求，生成响应
StudyManagement.Startup:Debug: M2: 传出响应
StudyManagement.Startup:Debug: M1: 传出响应
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 52.8954ms 200 text/plain;charset=utf-8
StudyManagement.Startup:Debug: M1: 传入请求
StudyManagement.Startup:Debug: M2: 传入请求
StudyManagement.Startup:Debug: M3: 处理请求，生成响应
StudyManagement.Startup:Debug: M2: 传出响应
StudyManagement.Startup:Debug: M1: 传出响应
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 34.3387ms 200 text/plain;charset=utf-8
```

**请求处理管道的中 3 个非常重要的知识点：**

* 所有的请求都会在每个中间件组件调用next()方法之前触发。
* 当中间件处理请求并产生响应时，请求处理流程在管道中开始反向传递。
* 所有的响应都会在每个中间件组件调用next()方法之前触发。

**乱码问题：(设置字符类型)**

`context.Response.ContentType = "text/plain; charset=utf-8";`

## 开发环境变量

* Development：开发环境
* Staging：演示（模式，临时）环境
* Production：正式（生产）环境

Ops：

* 使用`ASPNETCORE_ENVIRONMENT`环境变量设置开发环境。
* 在开发机上，在`launchSettings.json`文件中设置环境变量。
* 在Staging和Production环境时，尽量在操作系统设置环境变量。
* 使用`IHostEnvironment`服务访问运行时环境
* 除了标准环境之外还支持自定义环境（UAT、QA等）

```
//如果环境是Development serve Developer Exception Page
if（env.IsDevelopment()）
{
   app.UseDeveloperExceptionPage();
}
//else提供具有应用程序支持的用户友好错误页面联系信息
  else if (env.IsStaging() || env.IsProduction() || env.IsEnvironment("UAT")){
               app.UseExceptionHandler("/Error");
           }
```

## 依赖注入

一表搞懂`Scoped`、`Transient`、`Singleton`三个依赖注入服务

| 服务类型          | 同一个HTTP请求的范围内 | 横跨多个不同的HTTP请求 |
| ------------- | ------------- | ------------- |
| Scoped（作用域）   | 同一个实例         | 新实例           |
| Transient（瞬时） | 新实例           | 新实例           |
| Singleton（单例） | 同一个实例         | 同一个实例         |
