Ten artykuł jest lustrzanym artykułem tłumaczenia maszynowego, kliknij tutaj, aby przejść do oryginalnego artykułu.

Widok: 59583|Odpowiedź: 1

[Źródło] ASP.NET Rdzeń (7) Dogłębna analiza kodu źródłowego frameworka

[Skopiuj link]
Opublikowano 2021-3-24 13:43:28 | | |
Recenzja:

ASP.NET Core (VI) DI ręcznie uzyskuje metodę wstrzykiwania obiektów
https://www.itsvse.com/thread-9595-1-1.html

ASP.NET Core (pięć) opiera się na rozproszonych transakcjach CAP
https://www.itsvse.com/thread-9593-1-1.html

ASP.NET Filtr Core(4) zunifikowany walidacja modelu modelu ModelState
https://www.itsvse.com/thread-9589-1-1.html

ASP.NET Rdzeń (iii) Dynamicznie twórz instancje za pomocą ActivatorUtilities
https://www.itsvse.com/thread-9488-1-1.html

ASP.NET Rdzeń (2) Restart aplikacji za pomocą kodu
https://www.itsvse.com/thread-9480-1-1.html

ASP.NET Core (1) korzysta z buforowania Redis
https://www.itsvse.com/thread-9393-1-1.html
Zacznij od dołączenia otwartego adresu GitHub ASP.NET Core

Logowanie do linku jest widoczne.
Logowanie do linku jest widoczne.


asp.net Adres kodu źródłowego rdzenia
https://www.itsvse.com/thread-9394-1-1.html


Po utworzeniu nowego projektu ASP.NET Core 3.1, kod programu wygląda następująco:

Dogłębnie przyjrzeliśmy się kodowi wejściowemu połączonemu z kodem źródłowym GitHuba.

Kod hosta:Logowanie do linku jest widoczne.

Metoda CreateDefaultBuilder

Tutaj instancjonujemy obiekt HostBuilder, który dziedziczy z IHostBuilder, i dodajemy delegatów definiowanych przez system, takich jak :appsettings.json, appsettings. {env. EnvironmentName}.json pliku konfiguracyjnego, który ostatecznie zwróci: interfejs IHostBuilder.

Kod HostBuilder:Logowanie do linku jest widoczne.

Metoda Build zostanie ostatecznie wywołana.


public IHost Build()
{
    jeśli (_hostBuilt)
    {
        wyrzuć nowy InvalidOperationException(SR. BuildCalled);
    }
    _hostBuilt = prawdziwe;

    BuildHostConfiguration();
    CreateHostingEnvironment();
    CreateHostBuilderContext();
    BuildAppConfiguration();
    CreateServiceProvider();

    return _appServices.GetRequiredService<IHost>();
}
Metoda BuildHostConfiguration

prywatna _hostConfiguration IConfiguracji;
IConfigurationBuilder configBuilder = nowy ConfigurationBuilder()
Wywołaj delegata, aby dodać konfigurację na kolej

Metoda CreateHostingEnvironment

prywatne HostingEnvironment _hostingEnvironment;
_hostingEnvironment = nowy HostEnvironment()
{
    ApplicationName = _hostConfiguration[HostDefaults.ApplicationKey],
    EnvironmentName = _hostConfiguration[HostDefaults.EnvironmentKey] ?? Środowiska. Produkcja,
    ContentRootPath = ResolveContentRootPath(_hostConfiguration[HostDefaults.ContentRootKey], AppContext.BaseDirectory),
};
Metoda CreateHostBuilderContext

prywatny HostBuilderContext _hostBuilderContext;
_hostBuilderContext = nowy HostBuilderContext(Właściwości)
{
    HostEnvironment = _hostingEnvironment,
    Konfiguracja = _hostConfiguration
};
Metoda BuildAppConfiguration

Ponownie integruj informacje konfiguracyjne

IConfigurationBuilder configBuilder = nowy ConfigurationBuilder()
                . SetBasePath(_hostingEnvironment.ContentRootPath)
                . AddConfiguration(_hostConfiguration, shouldDisposeConfiguration: true);
_appConfiguration = configBuilder.Build();
            _hostBuilderContext.Konfiguracja = _appConfiguration;
Metoda CreateServiceProvider

var services = new ServiceCollection();
Zarejestruj usługę, wywołaj delegata i dodaj usługę zdefiniowaną przez użytkownika.

Metoda rozszerzenia GenericHostBuilderExtensions

Logowanie do linku jest widoczne.

Metoda rozszerzenia ConfigureWebHost

Aby zarejestrować GenericWebHostService jako usługę backendową:


Budowniczcie. ConfigureServices((context, services) => services. AddHostedService<GenericWebHostService>());
Kod GenericWebHostService:Logowanie do linku jest widoczne.


publicznie asynchroniczne zadanie StartAsync(CancellationToken cancellationToken)
        {
            HostingEventSource.Log.HostStart();

            var serverAddressesFeature = Server.Features.Get<IServerAddressesFeature>();
            var addresses = serverAddressesFeature?. Adresy;
            if (adresuje != adresy null & !. IsReadOnly & adresy. Count == 0)
            {
                var urls = Configuration[WebHostDefaults.ServerUrlsKey];
                if (!string. IsNullOrEmpty(urls))
                {
                    serwerAddressesFeature!. PreferHostingUrls = WebHostUtilities.ParseBool(Configuration, WebHostDefaults.PreferHostingUrlsKey);

                    foreach (wartość var w URL-ach. Split('; ', StringSplitOptions.RemoveEmptyEntries))
                    {
                        adresy. add(value);
                    }
                }
            }

            RequestDelegate? zastosowanie = null;

            spróbuj
            {
                var configure = Options.ConfigureApplication;

                if (configure == null)
                {
                    wyrzuć nowy InvalidOperationException($"Nie skonfigurowana żadna aplikacja. Proszę określić aplikację za pomocą IWebHostBuilder.UseStartup, IWebHostBuilder.Configure, lub określić asembl startowy za pomocą {nameof(WebHostDefaults.StartupAssemblyKey)} w konfiguracja hosta webowego.");
                }

                var builder = ApplicationBuilderFactory.CreateBuilder(Server.Features);

                foreach (var filter in StartupFilters.Reverse())
                {
                    configure = filter. konfiguruj (konfiguruj);
                }

                configure(builder);

                Buduj potok żądań
                zastosowanie = twórca. build();
            }
            złapanie (Wyjątek ex)
            {
                Logger.ApplicationError(ex);

                jeśli (! Options.WebHostOptions.CaptureStartupErrors)
                {
                    rzut;
                }

                var showDetailedErrors = HostEnvironment.IsDevelopment() || Options.WebHostOptions.SzczegółoweBłędy;

                application = ErrorPageBuilder.BuildErrorPageApplication(HostingEnvironment.ContentRootFileProvider, Logger, showDetailedErrors, ex);
            }

            var httpApplication = nowy HostingApplication(application, Logger, DiagnosticListener, HttpContextFactory);

            await Server.StartAsync(httpApplication, cancellationToken);

            if (adresuje != null)
            {
                foreach (adres var w adresach)
                {
                    LifetimeLogger.ListeningOnAddress(address);
                }
            }

            if (Logger.IsEnabled(LogLevel.Debug))
            {
                foreach (var assembly in Options.WebHostOptions.GetFinalHostingStartupAssemblies())
                {
                    Logger.StartupAssemblyLoaded(assembly);
                }
            }

            if (Options.HostingStartupExceptions != null)
            {
                foreach (wyjątek zmienny w Options.HostingStartupExceptions.InnerExceptions)
                {
                    Logger.HostingStartupAssemblyError(exception);
                }
            }
        }


var webhostBuilder = nowy GenericWebHostBuilder(builder, webHostBuilderOptions);
Logowanie do linku jest widoczne.

Metoda rozszerzenia WebHostBuilderExtensions

Zapewnia obiekt startupType dla wywołań IWebHostBuilder.

ten IWebHostBuilder hostBuilder
jeśli (hostBuilder is ISupportsStartup supportsStartup)
{
    return supportsStartup.UseStartup(startupType);
}
Logowanie do linku jest widoczne.

GenericWebHostBuilder Metoda prywatna GenericWebHostBuilder

Dynamicznie instancjonuj nasz obiekt Startup:

przypadek?? = ActivatorUtilities.CreateInstance(nowy HostServiceProvider(webHostBuilderContext), startType);
kontekst. Właściwości[_startupKey] = instancja;
Szukaj metody ConfigureServices

var configureServicesBuilder = StartupLoader.FindConfigureServicesDelegate(startupType, context. HostingEnvironment.EnvironmentName);
                var configureServices = configureServicesBuilder.Build(instance);

internal static ConfigureServicesBuilder FindConfigureServicesDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Wpis startupType, string environmentName)
        {
            var servicesMethod = FindMethod(startupType, "Configure{0}Services", environmentName, typeof(IServiceProvider), required: false)
                ?? FindMethod(startType, "Configure{0}Services", environmentName, typeof(void), required: false);
            return new ConfigureServicesBuilder(servicesMethod);
Szukaj metody ConfigureContainer

var configureContainerBuilder = StartupLoader.FindConfigureContainerDelegate(startupType, context. HostingEnvironment.EnvironmentName);

internal static ConfigureContainerBuilder FindConfigureContainerDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Wpisz startupType, string environmentName)
        {
            var configureMethod = FindMethod(startupType, "Configure{0}Container", environmentName, typeof(void), required: false);
            return new ConfigureContainerBuilder(configureMethod);
        }
Poszukaj metody Configure

configureBuilder = StartupLoader.FindConfigureDelegate(startType, context. HostingEnvironment.EnvironmentName);

internal static ConfigureBuilder FindConfigureDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Wpisz startupType, string environmentName)
{
    var configureMethod = FindMethod(startupType, "Configure{0}", environmentName, typeof(void), required: true)!;
    return new ConfigureBuilder(configureMethod);
}
Generowany metodą Build ConfigureBuilder, kod źródłowy wygląda następująco:

Prywatna klasa ConfigureBuilder
        {
            public ConfigureBuilder(MethodInfo configure)
            {
                MethodInfo = konfigurować;
            }

            public MethodInfo MethodInfo { get; }

            public<IApplicationBuilder> Action Build (instancja obiektu)
            {
                return (applicationBuilder) => Invoke(instancja, applicationBuilder);
            }

            private void Invoke(instancja obiektu, IApplicationBuilder builder)
            {
                var serviceProvider = builder. ApplicationServices;
                var parameterInfos = MethodInfo.GetParameters();
                parametry var = nowy obiekt[parameterInfos.Length];
                dla (indeks zmienny = 0; index < parametrInfos.Length; indeks++)
                {
                    var parameterInfo = parameterInfos[index];
                    if (parameterInfo.ParameterType == typeof(IApplicationBuilder))
                    {
                        parametry[index] = budownicza;
                    }
                    else
                    {
                        spróbuj
                        {
                            parameters[index] = serviceProvider.GetRequiredService(parameterInfo.ParameterType);
                        }
                        złapanie (Wyjątek ex)
                        {
                            throw new InvalidOperationException(
                                Resources.FormatMiddlewareFilter_ServiceResolutionFail(
                                    parameterInfo.ParameterType.FullName,
                                    parameterInfo.Name,
                                    MethodInfo.Name,
                                    MethodInfo.DeclaringType.FullName),
                                ex);
                        }
                    }
                }
                MethodInfo.Invoke(instancja, parametry);
            }
        }
Metoda uruchomienia

Adres metody rozszerzenia HostingAbstractionsHostExtensions:

Logowanie do linku jest widoczne.


Ostatecznie dzwoni:

/// <summary>
        Uruchamia aplikację i zwraca zadanie, które kończy się tylko po wyzwoleniu tokena lub wyłączeniu.
        /// </summary>
        <nazwa parametrów="host">The <see cref="IHost"/> do uruchomienia.</param>
        <nazwa parametru="token">Token wywołujący wyłączenie.</param>
        <returns><zobacz cref="Task"/> reprezentuje operację asynchroniczną.</returns>
        publiczny statyczny asynchroniczny Task RunAsync (ten IHost host, token CancellationToken = domyślny)
        {
            spróbuj
            {
                Czekajcie na gospodarza. StartAsync(token). ConfigureAwait(false);

                Czekajcie na gospodarza. WaitForShutdownAsync(token). ConfigureAwait(false);
            }
            W końcu
            {
                if (host is IAsyncDisposable asyncDisposable)
                {
                    await asyncDisposable.DisposeAsync(). ConfigureAwait(false);
                }
                else
                {
                    gospodarza. Dispose();
                }

            }
        }
Wcześniej, gdy tworzyłem usługę, rejestrowałem się do usługi IHost, a kod był następujący:

usługi. AddSingleton<IHost>(_ =>
            {
                return new Internal.Host(_appServices,
                    _appServices.GetRequiredService<IHostApplicationLifetime>(),
                    _appServices.GetRequiredService<ILogger<Internal.Host>>(),
                    _appServices.GetRequiredService<IHostLifetime>(),
                    _appServices.GetRequiredService<IOptions<HostOptions>>());
            });
Metoda StartAsync

Adres:Logowanie do linku jest widoczne.

publicznie asynchroniczne Zadanie StartAsync(CancellationToken cancellationToken = domyślne)
        {
            _logger. Starting();

            używając var combinedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _applicationLifetime.ApplicationStopping);
            CancellationToken combinedCancellationToken = combinedCancellationTokenSource.Token;

            await _hostLifetime.WaitForStartAsync(combinedCancellationToken). ConfigureAwait(false);

            combinedCancellationToken.ThrowIfCancellationRequested();
            _hostedServices = Services.GetService<IEnumerable<IHostedService>>();

            foreach (IHostedService hostedService w _hostedServices)
            {
                // Fire IHostedService.Start
                await hostedService.StartAsync(combinedCancellationToken). ConfigureAwait(false);

                jeśli (hostedService is BackgroundService backgroundService)
                {
                    _ = HandleBackgroundException(backgroundService);
                }
            }

            // Fire IHostApplicationLifetime.Started
            _applicationLifetime.NotifyStarted();

            _logger. Started();
        }
(Koniec)




Poprzedni:Późne relacje nowych osób
Następny:Błąd rdzenia .NET w pakiecie aplikacji Linux Failure Processing
Opublikowano 2021-9-22 20:45:12 |
Naucz się uczyć...
Zrzeczenie się:
Całe oprogramowanie, materiały programistyczne lub artykuły publikowane przez Code Farmer Network służą wyłącznie celom edukacyjnym i badawczym; Powyższe treści nie mogą być wykorzystywane do celów komercyjnych ani nielegalnych, w przeciwnym razie użytkownicy ponoszą wszelkie konsekwencje. Informacje na tej stronie pochodzą z Internetu, a spory dotyczące praw autorskich nie mają z nią nic wspólnego. Musisz całkowicie usunąć powyższą zawartość z komputera w ciągu 24 godzin od pobrania. Jeśli spodoba Ci się program, wspieraj oryginalne oprogramowanie, kup rejestrację i korzystaj z lepszych, autentycznych usług. W przypadku naruszenia praw prosimy o kontakt mailowy.

Mail To:help@itsvse.com