王井锐 發表於 2026-4-24 16:41:00

.NET 管道、中间件、配置系统、依赖注入 (DI) 生命周期

<h2>一、请求处理管道(Pipeline)</h2>
<div>&nbsp;</div>
<h3>1. 是什么?</h3>
<div>&nbsp;</div>
<div>ASP.NET Core 处理 HTTP 请求的一条流水线。
<div>&nbsp;</div>
请求进来 → 依次经过多个中间件 → 响应返回。</div>
<div>&nbsp;</div>
<h3>2. 核心特点</h3>
<div>&nbsp;</div>
<ul>
<li>单向进入,双向返回
<div>&nbsp;</div>
请求:从上到下执行中间件
<div>&nbsp;</div>
响应:从下到上原路返回</li>
<li>顺序至关重要
<div>&nbsp;</div>
先注册的中间件先执行</li>
<li>可短 - circuit(短路)
<div>&nbsp;</div>
某个中间件直接返回响应,后面的中间件不再执行</li>
</ul>
<div>&nbsp;</div>
<h3>3. 形象比喻</h3>
<div>&nbsp;</div>
<div>管道 = 医院看病流程
<div>&nbsp;</div>
挂号 → 分诊 → 看病 → 缴费 → 拿药
<div>&nbsp;</div>
请求必须按顺序走完全程。</div>
<div>&nbsp;</div>
<hr>
<div>&nbsp;</div>
<h2>二、中间件(Middleware)</h2>
<div>&nbsp;</div>
<h3>1. 是什么?</h3>
<div>&nbsp;</div>
<div>管道里的每一个处理环节,是一个可以处理请求 / 响应的独立组件。</div>
<div>&nbsp;</div>
<h3>2. 两种写法</h3>
<div>&nbsp;</div>
<h4>① 内联中间件</h4>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>app.Use(async (context, next) =&gt;
{
    // 请求进来
    Console.WriteLine("请求处理前");

    // 调用下一个中间件
    await next();

    // 响应返回
    Console.WriteLine("响应处理后");
});
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<h4>② 自定义中间件类</h4>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>public class MyMiddleware
{
    private readonly RequestDelegate _next;

    public MyMiddleware(RequestDelegate next)
    {
      _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
      // 逻辑
      await _next(context);
    }
}
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<h3>3. 常用中间件(静态文件 → CORS → 路由 → 认证 → 授权 → 控制器)</h3>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();    // 路由
app.UseCors();       // 跨域
app.UseAuthentication(); // 认证
app.UseAuthorization();// 授权
app.MapControllers();
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<h3>4. 三个核心方法区别</h3>
<div>&nbsp;</div>
<ul>
<li><code>Use</code>:可以执行 next,也可以不执行(最常用)</li>
<li><code>Run</code>:短路,不调用 next,请求到此结束</li>
<li><code>Map</code>:按路径分支,如 /admin 走一套中间件</li>
</ul>
<div>&nbsp;</div>
<hr>
<div>&nbsp;</div>
<h2>三、配置系统(Configuration)</h2>
<div>&nbsp;</div>
<h3>1. 是什么?</h3>
<div>&nbsp;</div>
<div>ASP.NET Core 读取配置的统一系统,支持多数据源、热重载、强类型绑定。</div>
<div>&nbsp;</div>
<h3>2. 默认加载顺序(后面覆盖前面)</h3>
<div>&nbsp;</div>
<ol>
<li>appsettings.json</li>
<li>appsettings.{Environment}.json</li>
<li>用户机密(开发环境)</li>
<li>环境变量</li>
<li>命令行参数</li>
</ol>
<div>&nbsp;</div>
<h3>3. 读取配置的三种方式</h3>
<div>&nbsp;</div>
<h4>① 直接读</h4>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>var connStr = builder.Configuration["ConnectionStrings:Default"];
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<h4>② 绑定到强类型类(最佳实践)</h4>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>builder.Configuration.GetSection("Jwt").Bind&lt;JwtOptions&gt;();
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<h4>③ 注入 IOptions&lt;T&gt;</h4>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>public class Service(IOptions&lt;JwtOptions&gt; options)
{
}
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<h3>4. 三种 IOptions 区别</h3>
<div>&nbsp;</div>
<ul>
<li><code>IOptions&lt;T&gt;</code>:单例,不热更新</li>
<li><code>IOptionsSnapshot&lt;T&gt;</code>:作用域,每个请求重新加载</li>
<li><code>IOptionsMonitor&lt;T&gt;</code>:单例,实时热更新</li>
</ul>
<div>&nbsp;</div>
<hr>
<div>&nbsp;</div>
<h2>四、依赖注入(DI)与 生命周期</h2>
<div>&nbsp;</div>
<h3>1. 是什么?</h3>
<div>&nbsp;</div>
<div>框架自动帮你创建对象、管理对象生命周期、注入依赖。</div>
<div>&nbsp;</div>
<h3>2. 三大生命周期(面试必考)</h3>
<div>&nbsp;</div>
<h4>① Singleton(单例)</h4>
<div>&nbsp;</div>
<ul>
<li>整个应用只创建一个实例</li>
<li>线程不安全</li>
<li>适合:无状态、工具类、配置、日志</li>
</ul>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>builder.Services.AddSingleton&lt;IMyService, MyService&gt;();
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<h4>② Scoped(作用域)</h4>
<div>&nbsp;</div>
<ul>
<li>每个请求创建一个实例</li>
<li>请求结束销毁</li>
<li>最常用:EF Core DbContext、业务服务</li>
</ul>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>builder.Services.AddScoped&lt;IMyService, MyService&gt;();
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<h4>③ Transient(瞬时)</h4>
<div>&nbsp;</div>
<ul>
<li>每次使用都创建新实例</li>
<li>最轻量</li>
<li>适合:无状态、轻量级服务</li>
</ul>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>builder.Services.AddTransient&lt;IMyService, MyService&gt;();
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<h3>3. 生命周期禁止 “降级”(黄金规则)</h3>
<div>&nbsp;</div>
<div>长生命周期服务 不能 依赖 短生命周期服务</div>
<div>&nbsp;</div>
<div>错误:</div>
<div>&nbsp;</div>
<ul>
<li>Singleton → Scoped ❌</li>
<li>Singleton → Transient ❌</li>
</ul>
<div>&nbsp;</div>
<div>正确:</div>
<div>&nbsp;</div>
<ul>
<li>Scoped → Singleton ✅</li>
<li>Transient → Scoped / Singleton ✅</li>
</ul>
<div>&nbsp;</div>
<h3>4. 注入方式</h3>
<div>&nbsp;</div>
<ol>
<li>构造函数注入(官方推荐)</li>
<li>方法注入</li>
<li>属性注入(.NET 8+ 支持)</li>
</ol>
<div>&nbsp;</div>
<hr>
<div>&nbsp;</div>
<h1>一张表</h1>
<div>&nbsp;</div>
<div>
<div>
<div>&nbsp;</div>
</div>
<div>
<div>
<div>
<table>
<thead>
<tr><th>概念</th><th>核心作用</th><th>关键点</th></tr>
</thead>
<tbody>
<tr>
<td>管道</td>
<td>请求处理流程</td>
<td>顺序执行、双向往返、可短路</td>
</tr>
<tr>
<td>中间件</td>
<td>管道中的处理单元</td>
<td>Use/Run/Map、顺序决定功能</td>
</tr>
<tr>
<td>配置系统</td>
<td>读取配置</td>
<td>多源覆盖、强类型、热更新</td>
</tr>
<tr>
<td>Singleton</td>
<td>单例</td>
<td>全局一个、线程不安全</td>
</tr>
<tr>
<td>Scoped</td>
<td>作用域</td>
<td>一个请求一个、DbContext 专用</td>
</tr>
<tr>
<td>Transient</td>
<td>瞬时</td>
<td>每次都新实例</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div>&nbsp;</div>
<hr>
<div>&nbsp;</div>
<h3>总结</h3>
<div>&nbsp;</div>
<ol>
<li>管道是请求的必经之路,中间件是路上的关卡</li>
<li>中间件顺序决定功能能否正常运行(认证必须在授权前)</li>
<li>配置支持多来源,推荐用强类型 + IOptions</li>
<li>生命周期:Scoped 最常用,严禁长生命周期依赖短生命周期</li>
</ol><br><br>
来源:https://www.cnblogs.com/chuansheng/p/19913211
頁: [1]
查看完整版本: .NET 管道、中间件、配置系统、依赖注入 (DI) 生命周期