復習:
まずは ASP.NET Core GitHubのオープンソースアドレスを添付してください
ハイパーリンクのログインが見えます。
ハイパーリンクのログインが見えます。
Core 3.1 ASP.NET 新しいプロジェクトを作成した後、プログラムコードは以下の通りです。
エントリコードとGitHubのソースコードを組み合わせて深く掘り下げました。
ホストコード:ハイパーリンクのログインが見えます。
CreateDefaultBuilderメソッド
ここではIHostBuilderから継承したHostBuilderオブジェクトをインスタンス化し、:appsettings.json、appsettingsなどのシステム定義のデリゲートを追加します。 {env. EnvironmentName}.json設定ファイルであり、最終的にはIHostBuilderインターフェースを返します。
HostBuilderコード:ハイパーリンクのログインが見えます。
Buildメソッドは最終的に呼び出されます。
公開IHost Build()
{ もし(_hostBuilt) { 新しいInvalidOperationException(SR. BuildCalled); } _hostBuilt = 真;
BuildHostConfiguration(); CreateHostingEnvironment(); CreateHostBuilderContext(); BuildAppConfiguration(); CreateServiceProvider();
return _appServices.GetRequiredService<IHost>();
} BuildHostConfiguration メソッド
私設のIConfiguration_hostConfiguration; IConfigurationBuilder configBuilder = new ConfigurationBuilder() デリゲートに電話して設定を追加してもらう
CreateHostingEnvironment メソッド
private HostingEnvironment _hostingEnvironment; _hostingEnvironment = 新しいHostingEnvironment()
{ ApplicationName = _hostConfiguration[HostDefaults.ApplicationKey], EnvironmentName = _hostConfiguration[HostDefaults.EnvironmentKey] ?? 環境。生産、 ContentRootPath = ResolveContentRootPath(_hostConfiguration[HostDefaults.ContentRootKey], AppContext.BaseDirectory), }; CreateHostBuilderContextメソッド
private HostBuilderContext _hostBuilderContext; _hostBuilderContext = new HostBuilderContext(Properties)
{ HostingEnvironment = _hostingEnvironment, 構成 = _hostConfiguration }; BuildAppConfiguration メソッド
設定情報を再度統合します
IConfigurationBuilder configBuilder = new ConfigurationBuilder() . SetBasePath(_hostingEnvironment.ContentRootPath) . AddConfiguration(_hostConfiguration, shouldDisposeConfiguration: true); _appConfiguration = configBuilder.Build(); _hostBuilderContext.Configuration = _appConfiguration; CreateServiceProvider メソッド
var services = new ServiceCollection(); サービスを登録し、デリゲートを呼び出し、ユーザー定義サービスを追加します。
GenericHostBuilderExtensions 拡張メソッド
ハイパーリンクのログインが見えます。
ConfigureWebHost拡張メソッド
GenericWebHostServiceをバックエンドサービスとして登録するには:
ビルダー。 ConfigureServices((コンテキスト、サービス) => services。 AddHostedService<GenericWebHostService>()); 汎用WebHostServiceコード:ハイパーリンクのログインが見えます。
public async Task StartAsync(CancellationToken cancellationToken) { HostingEventSource.Log.HostStart();
var serverAddressesFeature = <IServerAddressesFeature>Server.Features.Get(); var addresses = serverAddressesFeature?. 住所; もし(addresses != null & !addresses. IsReadOnly & アドレス。 カウント == 0) { var urls = Configuration[WebHostDefaults.ServerUrlsKey]; もし(!string. IsNullOrEmpty(urls)) { serverAddressesFeature! PreferHostingUrls = WebHostUtilities.ParseBool(Configuration, WebHostDefaults.PreferHostingUrlsKey);
foreach(URLのvar値)。 スプリット('; ', StringSplitOptions.RemoveEmptyEntries)) { 住所。 加算(値); } } }
リクエストDelegate? application = null;
やってみて { var configure = Options.ConfigureApplication;
もし(構成 == null) { throw new InvalidOperationException($"No application configureed. IWebHostBuilder.UseStartup、IWebHostBuilder.Configure、または{nameof(WebHostDefaults.StartupAssemblyKey)}で起動アセンブリを指定するためにアプリケーションを指定してください。 ウェブホスト構成。」); }
var builder = ApplicationBuilderFactory.CreateBuilder(Server.Features);
foreach (StartupFilters.Reverse()のvarフィルター) { configure = filter。 コンフィギュア(コンフィギュア); }
コンフィギュア(ビルダー);
リクエストパイプラインを構築する 応用 = ビルダー。 Build(); } catch(例外例) { Logger.ApplicationError(ex);
もし(! Options.WebHostOptions.CaptureStartupErrors) { 投げる; }
var showDetailedErrors = HostingEnvironment.IsDevelopment() || Options.WebHostOptions.DetailedErrors;
application = ErrorPageBuilder.BuildErrorPageApplication(HostingEnvironment.ContentRootFileProvider, Logger, showDetailedErrors, ex); }
var httpApplication = new HostingApplication(application, Logger, DiagnosticListener, HttpContextFactory);
await Server.StartAsync(httpApplication, cancellationToken);
もし(addresss != null) { foreach(アドレス内のvarアドレス) { LifetimeLogger.ListeningOnAddress(address); } }
if (Logger.IsEnabled(LogLevel.Debug)) { foreach (var assembly in Options.WebHostOptions.GetFinalHostingStartupAssemblies()) { Logger.StartupAssemblyLoaded(assembly); } }
if (Options.HostingStartupExceptions != null) { foreach (var exception in Options.HostingStartupExceptions.InnerExceptions) { Logger.HostingStartupAssemblyError(exception); } } }
var webhostBuilder = new GenericWebHostBuilder(builder, webHostBuilderOptions); ハイパーリンクのログインが見えます。
WebHostBuilderExtensions 拡張メソッド
IWebHostBuilder呼び出しのためのstartupTypeオブジェクトを提供します。
このIWebHostBuilder hostBuilder if(hostBuilder はISupportsStartup supportsStartup)
{ return supportsStartup.UseStartup(startupType);
} ハイパーリンクのログインが見えます。
GenericWebHostBuilder プライベートメソッド GenericWebHostBuilder
Startupオブジェクトを動的にインスタンス化します:
インスタンス?? = ActivatorUtilities.CreateInstance(new HostServiceProvider(webHostBuilderContext), startupType); 文脈。 プロパティ[_startupKey] = インスタンス; ConfigureServicesメソッドを探してみてください
var configureServicesBuilder = StartupLoader.FindConfigureServicesDelegate(startupType, context. HostingEnvironment.EnvironmentName); var configureServices = configureServicesBuilder.Build(instance);
internal static ConfigureServicesBuilder FindConfigureServicesDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] タイプ startupType, string environmentName) { var servicesMethod = FindMethod(startupType, "Configure{0}Services", environmentName, typeof(IServiceProvider), required: false) ?? FindMethod(startupType, "Configure{0}Services", environmentName, typeof(void), required: false); 新しいConfigureServicesBuilder(servicesMethod)を返します; ConfigureContainerメソッドを探してみてください
var configureContainerBuilder = StartupLoader.FindConfigureContainerDelegate(startupType, context. HostingEnvironment.EnvironmentName);
internal static ConfigureContainerBuilder FindConfigureContainerDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] タイプ startupTypeType, string environmentName) { var configureMethod = FindMethod(startupType, "Configure{0}Container", environmentName, typeof(void), required: false); return new ConfigureContainerBuilder(configureMethod); } コンフィケーションメソッドを探してみてください
configureBuilder = StartupLoader.FindConfigureDelegate(startupType, context. HostingEnvironment.EnvironmentName);
internal static ConfigureBuilder FindConfigureDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Type startupType, string environmentName)
{ var configureMethod = FindMethod(startupType, "Configure{0}", environmentName, typeof(void), required: true)!; return new ConfigureBuilder(configureMethod);
} ConfigureBuilderのビルドメソッドで呼び出されたソースコードは以下の通りです:
プライベートクラスコンフィギュービルダー { public ConfigureBuilder(MethodInfo configure) { MethodInfo = configure; }
public MethodInfo MethodInfo { get; }
public Action<IApplicationBuilder> Build(オブジェクトインスタンス) { return (applicationBuilder) => Invoke(instance, applicationBuilder); }
private void Invoke(object instance, IApplicationBuilder builder) { var serviceProvider = builder. ApplicationServices; var parameterInfos = MethodInfo.GetParameters(); var parameters = new object[parameterInfos.Length]; (var index = 0; index < parameterInfos.Length; index++) { var parameterInfo = parameterInfos[index]; if (parameterInfo.ParameterType == typeof(IApplicationBuilder)) { パラメータ[index] = ビルダー; } そうでなければ { やってみて { parameters[index] = serviceProvider.GetRequiredService(parameterInfo.ParameterType); } catch(例外例) { 新しいInvalidOperationException( Resources.FormatMiddlewareFilter_ServiceResolutionFail( parameterInfo.ParameterType.FullName, parameterInfo.Name、 MethodInfo.Name、 MethodInfo.DeclaringType.FullName), 例); } } } MethodInfo.Invoke(instance, parameters); } } ラン法
HostingAbstractionsHostExtensions 拡張メソッドアドレス:
ハイパーリンクのログインが見えます。
最終的にはこう呼ばれます:
/// <summary> アプリケーションを実行し、トークンがトリガーされるかシャットダウンがトリガーされた場合にのみ完了するタスクを返します。 /// </summary> <param name="host">The <see cref="IHost"/> を実行してください。</param> <param name="token">シャットダウンをトリガーするトークン。</param> <returns>非同期操作を表す <参照 cref=「タスク」/>。</returns> 公開静的非同期タスク RunAsync(このIHostホスト、CancellationTokenトークン=デフォルト) { やってみて { ホストを待つ。 StartAsync(token). ConfigureAwait(false);
ホストを待つ。 WaitForShutdownAsync(token)。 ConfigureAwait(false); } 最終的に { もし(ホストはIAsyncDisposable asyncDisposable) { waitasyncDisposable.DisposeAsync()。 ConfigureAwait(false); } そうでなければ { ホスト。 Dispose(); }
} } 以前、サービスを構築していたときはIHostサービスに登録していましたが、コードは以下の通りです:
サービス。 AddSingleton<IHost>(_ => { return new Internal.Host(_appServices, _appServices.GetRequiredService<IHostApplicationLifetime>(), _appServices.GetRequiredService<ILogger<Internal.Host>>(), _appServices.GetRequiredService<IHostLifetime>(), _appServices.GetRequiredService<IOptions<HostOptions>>()); }); StartAsyncメソッド
住所:ハイパーリンクのログインが見えます。
公開非同期タスク StartAsync(CancellationToken cancellationToken = default) { _logger。 スターティング();
var combinedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _applicationLifetime.ApplicationStopping); キャンセルトークン combinedCancellationToken = combinedCancellationTokenSource.Token;
await _hostLifetime.WaitForStartAsync(combinedCancellationToken). ConfigureAwait(false);
combinedCancellationToken.ThrowIfCancellationRequested(); _hostedServices = Services.GetService<IEnumerable<IHostedService>>();
foreach(_hostedServices年はIHostedServiceホストサービス) { 火災サービス開始 await hostedService.StartAsync(combinedCancellationToken). ConfigureAwait(false);
if(hostedService は BackgroundService backgroundService) { _ = HandleBackgroundException(backgroundService); } }
ファイア IHostアプリケーションLifetime。開始 _applicationLifetime.NotifyStarted();
_logger。 Started(); } (終わり)
|