日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

.NET8 WebApplication剖析

發布時間:2023/11/5 C# 57 coder
生活随笔 收集整理的這篇文章主要介紹了 .NET8 WebApplication剖析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? WebApplication 是用于配置HTTP管道和路由的web應用程序,接來下我將一一拆解它的組成。

/// <summary>
/// The web application used to configure the HTTP pipeline, and routes.
/// </summary>
[DebuggerDisplay("{DebuggerToString(),nq}")]
[DebuggerTypeProxy(typeof (WebApplication.WebApplicationDebugView))]
public sealed class WebApplication : IHost,IDisposable,IApplicationBuilder,IEndpointRouteBuilder,IAsyncDisposable

IHost

? 首先Web應用是一個程序,而 IHost 就是程序的抽象

public interface IHost : IDisposable
{
  IServiceProvider Services { get; }
  Task StartAsync(CancellationToken cancellationToken = default (CancellationToken));
  Task StopAsync(CancellationToken cancellationToken = default (CancellationToken));
}

? 一個程序具備啟動、停止生命周期,這很好理解。我要說的是 IServiceProvider ,他非常關鍵,后面會在依賴注入章節來詳細解釋。目前你只需要知道他是一個服務供應商就可以了,就可以通過他獲取想要的服務,但前提是你在IOC容器中注冊過。

? Host StartAsync 代碼流如下:

await host._hostLifetime.WaitForStartAsync(token1).ConfigureAwait(false); // 注冊start程序
host.Services.GetService<IStartupValidator>()?.Validate(); // 校驗
IHostedLifecycleService.StartingAsync
IHostedService.StartAsync
IHostedLifecycleService.StartedAsync
host._applicationLifetime.NotifyStarted();

? StopAsync 類似,代碼流如下:

IHostedLifecycleService.StoppingAsync
IHostedService.StopAsync
IHostedLifecycleService.StoppedAsync
this._logger.StoppedWithException((Exception) ex);

? 值得注意的是 IStartupValidatorIHostedServiceIHostedLifecycleService 分別為我們提供不同的鉤子,只需要向容器注冊即可加入我們自定義的業務邏輯。

IApplicationBuilder

? WebApplication 實現 IApplicationBuilder 具有pipeline機制。

IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);
RequestDelegate Build();

? 這里要解釋一下pipeline,管道是.NET中非常普及的一個概念,內核是切面編程,同樣的在后續我們會有專門的章節來例舉它。現在你只需要知道,他是一個洋蔥模型。

? 同時,IApplicationBuilder 從命名上就表達了這是一個構建者模式,因此 WebApplication 提供了 Build

public WebApplication Build()
{
  this._hostApplicationBuilder.Services.Add(this._genericWebHostServiceDescriptor);
  this.Host.ApplyServiceProviderFactory(this._hostApplicationBuilder);
  this._builtApplication = new WebApplication(this._hostApplicationBuilder.Build());
  return this._builtApplication;
}

? 篇幅問題這里不展開討論,但在Build方法中會有四個鉤子被執行

public IHostBuilder ConfigureHostConfiguration(Action<IConfigurationBuilder> configureDelegate)
public IHostBuilder ConfigureAppConfiguration(Action<HostBuilderContext, IConfigurationBuilder> configureDelegate)
public IHostBuilder ConfigureServices(Action<HostBuilderContext, IServiceCollection> configureDelegate)
public IHostBuilder ConfigureContainer<TContainerBuilder>(Action<HostBuilderContext, TContainerBuilder> configureDelegate)

? 最終服務容器會被標記成只讀

IEndpointRouteBuilder

? IEndpointRouteBuilder為程序定義路由構建的約定。

ICollection<EndpointDataSource> DataSources { get; }

? 這是 WebApplication 中的實現,可以看到 EndpointDataSource 的實現會被組合進來。

public IReadOnlyList<Endpoint> Endpoints
{
  get
  {
    EndpointDataSource requiredService = this._webApplication.Services.GetRequiredService<EndpointDataSource>();
    return requiredService is CompositeEndpointDataSource endpointDataSource && endpointDataSource.DataSources.Intersect<EndpointDataSource>((IEnumerable<EndpointDataSource>) this._webApplication.DataSources).Count<EndpointDataSource>() != this._webApplication.DataSources.Count ? new CompositeEndpointDataSource((IEnumerable<EndpointDataSource>) this._webApplication.DataSources).Endpoints : requiredService.Endpoints;
  }
}

? EndpointDataSource實際上就是一組 Endpoint,而 Endpoint 是 AspNetCore 下極其重要的一節,同樣會在后續展開講。現在你只需要知道,它表示一個處理 HTTP 請求的終點,包含了處理請求的邏輯和相關的元數據。

IAsyncDisposable

? IAsyncDisposable 是 .NET Core 2.0 引入的一個接口,用于異步釋放資源的模式。它是 IDisposable 接口的異步版本。某些資源的釋放可能涉及到異步操作,使用 IDisposable 接口的同步釋放模式可能會導致阻塞線程,影響應用程序的性能和響應性。

public interface IAsyncDisposable
{
  ValueTask DisposeAsync();
}

? 在使用完該對象后,可以使用 await using語法糖或直接調用 ``DisposeAsync()` 方法來釋放資源。

Run

? Run 函數是 WebApplication 的啟動按鈕,你可以傳遞一個url,加入到監聽列表

public void Run([StringSyntax("Uri")] string? url = null)
{
  this.Listen(url);
  // public static void Run(this IHost host) => host.RunAsync().GetAwaiter().GetResult();
  HostingAbstractionsHostExtensions.Run(this);
}

? HostingAbstractionsHostExtensions.Run的源碼相對簡單,host的 StartAsyncWaitForShutdownAsync 在上面都介紹了,WebApplicationDisposeAsync 也在finally塊中觸發

public static async Task RunAsync(this IHost host, CancellationToken token = default (CancellationToken))
{
  try
  {
    ConfiguredTaskAwaitable configuredTaskAwaitable = host.StartAsync(token).ConfigureAwait(false);
    await configuredTaskAwaitable;
    configuredTaskAwaitable = host.WaitForShutdownAsync(token).ConfigureAwait(false);
    await configuredTaskAwaitable;
  }
  finally
  {
    if (host is IAsyncDisposable asyncDisposable)
      await asyncDisposable.DisposeAsync().ConfigureAwait(false);
    else
      host.Dispose();
  }
}

? 上面有個很有意思的點是,為什么要在finally塊中觸發?這是因為Host的生命周期函數都用了聯合取消令牌,這是一種安全取消協作模式,在令牌取消后會觸發一個 OperationCanceledException 異常,進而在這種情況下還能夠正常處理銷毀工作,這是一種非常優秀的編程習慣。

總結

以上是生活随笔為你收集整理的.NET8 WebApplication剖析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。