この記事は機械翻訳のミラー記事です。元の記事にジャンプするにはこちらをクリックしてください。

眺める: 59583|答える: 1

[出典] ASP.NET コア(7) フレームワークソースコードの詳細な分析

[リンクをコピー]
2021年3月24日 13:43:28に投稿 | | |
復習:

ASP.NET Core (VI) DIはオブジェクト注入の方法を手動で取得します
https://www.itsvse.com/thread-9595-1-1.html

ASP.NET コア(5)はCAP分散トランザクションに基づいています
https://www.itsvse.com/thread-9593-1-1.html

ASP.NET Core(4) フィルター 統一モデルステートモデル検証
https://www.itsvse.com/thread-9589-1-1.html

ASP.NET コア(iii) ActivatorUtilitiesを用いて動的にインスタンスを作成する
https://www.itsvse.com/thread-9488-1-1.html

ASP.NET コア(2) コードによるアプリケーションの再起動
https://www.itsvse.com/thread-9480-1-1.html

ASP.NET Core(1)はRedisキャッシュを使用しています
https://www.itsvse.com/thread-9393-1-1.html
まずは ASP.NET Core GitHubのオープンソースアドレスを添付してください

ハイパーリンクのログインが見えます。
ハイパーリンクのログインが見えます。


asp.net コアソースコードアドレス
https://www.itsvse.com/thread-9394-1-1.html


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();
        }
(終わり)




先の:遅れて来た新参者の報告
次に:Linuxの処理失敗アプリケーションバンドルにおける.NET Coreエラー
2021年9月22日 20:45:12に投稿 |
学ぶことを...
免責事項:
Code Farmer Networkが発行するすべてのソフトウェア、プログラミング資料、記事は学習および研究目的のみを目的としています。 上記の内容は商業的または違法な目的で使用されてはならず、そうでなければ利用者はすべての結果を負うことになります。 このサイトの情報はインターネットからのものであり、著作権紛争はこのサイトとは関係ありません。 ダウンロード後24時間以内に上記の内容を完全にパソコンから削除してください。 もしこのプログラムを気に入ったら、正規のソフトウェアを支持し、登録を購入し、より良い本物のサービスを受けてください。 もし侵害があれば、メールでご連絡ください。

Mail To:help@itsvse.com