Questo articolo è un articolo speculare di traduzione automatica, clicca qui per saltare all'articolo originale.

Vista: 59583|Risposta: 1

[Fonte] ASP.NET Core (7) Analisi approfondita del codice sorgente del framework

[Copiato link]
Pubblicato il 24-03-2021 13:43:28 | | |
Recensione:

ASP.NET Core (VI) DI ottiene manualmente il metodo di iniezione degli oggetti
https://www.itsvse.com/thread-9595-1-1.html

ASP.NET Core (cinque) si basa sulle transazioni distribuite CAP
https://www.itsvse.com/thread-9593-1-1.html

ASP.NET Filtro Core(4) validazione unificata del modello ModelState
https://www.itsvse.com/thread-9589-1-1.html

ASP.NET Core (iii) Creare dinamicamente istanze usando ActivatorUtilities
https://www.itsvse.com/thread-9488-1-1.html

ASP.NET Core (2) Riavvia l'applicazione tramite codice
https://www.itsvse.com/thread-9480-1-1.html

ASP.NET Core (1) utilizza la cache Redis
https://www.itsvse.com/thread-9393-1-1.html
Inizia allegando l'indirizzo open source ASP.NET Core GitHub

Il login del link ipertestuale è visibile.
Il login del link ipertestuale è visibile.


asp.net Indirizzo del codice sorgente principale
https://www.itsvse.com/thread-9394-1-1.html


Dopo aver creato un nuovo progetto ASP.NET Core 3.1, il codice del programma è il seguente:

Abbiamo approfondito il codice di ingresso combinato con il codice sorgente di GitHub.

Codice host:Il login del link ipertestuale è visibile.

Metodo CreateDefaultBuilder

Qui istanziamo un oggetto HostBuilder, che eredita da IHostBuilder, e aggiungiamo delegati definiti dal sistema, come :appsettings.json, appsettings. {env. EnvironmentName}.json file di configurazione, che alla fine restituirà: interfaccia IHostBuilder.

Codice HostBuilder:Il login del link ipertestuale è visibile.

Il metodo Build verrà infine chiamato.


Build pubblica IHost()
{
    se (_hostBuilt)
    {
        throw new InvalidOperationException(SR. BuildCalled);
    }
    _hostBuilt = vero;

    BuildHostConfiguration();
    CreaAmbienteOspiteHost();
    CreaHostCostruttoreContesto();
    BuildAppConfiguration();
    CreateServiceProvider();

    ritorno _appServices.GetRequiredService<IHost>();
}
Metodo BuildHostConfiguration

_hostConfiguration privata di Iconfigurazione;
IConfigurationBuilder configBuilder = nuovo ConfigurationBuilder()
Chiama il delegato per aggiungere configurazione a turno

Metodo CreateHostingEnvironment

Hosted Environment privato _hostingEnvironment;
_hostingEnvironment = nuovo Ambiente di Host()
{
    ApplicationName = _hostConfiguration[HostDefaults.ApplicationKey],
    AmbienteName = _hostConfiguration[HostDefaults.EnvironmentKey] ?? Ambienti. Produzione,
    ContentRootPath = ResolveContentRootPath(_hostConfiguration[HostDefaults.ContentRootKey], AppContext.BaseDirectory),
};
Metodo CreateHostBuilderContext

privato HostBuilderContext _hostBuilderContext;
_hostBuilderContext = nuovo HostBuilderContext(Proprietà)
{
    HostingEnvironment = _hostingEnvironment,
    Configurazione = _hostConfiguration
};
Metodo BuildAppConfiguration

Integra nuovamente le informazioni di configurazione

IConfigurationBuilder configBuilder = nuovo ConfigurationBuilder()
                . SetBasePath(_hostingEnvironment.ContentRootPath)
                . AddConfiguration(_hostConfiguration, shouldDisposeConfiguration: true);
_appConfiguration = configBuilder.Build();
            _hostBuilderContext.Configuration = _appConfiguration;
Metodo CreateServiceProvider

var services = nuova ServiceCollection();
Registra un servizio, chiama un delegato e aggiungi un servizio definito dall'utente.

Metodo di estensione GenericHostBuilderExtensions

Il login del link ipertestuale è visibile.

Metodo di estensione ConfigureWebHost

Per registrare GenericWebHostService come servizio backend:


muratore. ConfigureServices((contesto, servizi) => servizi. AddHostedService<GenericWebHostService>());
GenericWebHostService Code:Il login del link ipertestuale è visibile.


Task StartAsync async pubblico(CancellationToken cancellationToken)
        {
            HostingEventSource.Log.HostStart();

            var serverAddressesFeature = Server.Features.Get<IServerAddressesFeature>();
            var addresses = serverAddressesFeature?. Indirizzi;
            se (indirizzi != null && !indirizzi. IsReadOnly & & indirizzi. Count == 0)
            {
                var urls = Configuration[WebHostDefaults.ServerUrlsKey];
                se (!string. IsNullOrEmpty(urls))
                {
                    CaratteristicaIndirizziServer!. PreferHostingUrls = WebHostUtilities.ParseBool(Configuration, WebHostDefaults.PreferHostingUrlsKey);

                    Foreach (valore var in URL. Split('; ', StringSplitOptions.RemoveEmptyEntrries))
                    {
                        indirizzi. Aggiunge (valore);
                    }
                }
            }

            RichiedereDelegare? applicazione = nullo;

            prova
            {
                var configure = Options.ConfigureApplication;

                if (configura == null)
                {
                    throw new InvalidOperationException($"Nessuna applicazione configurata. Si prega di specificare un'applicazione tramite IWebHostBuilder.UseStartup, IWebHostBuilder.Configure, oppure specificare l'assembly di avvio tramite {nameof(WebHostDefaults.StartupAssemblyKey)} nel configurazione dell'host web.");
                }

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

                foreach (var filter in StartupFilters.Reverse())
                {
                    configura = filtro. Configure(configure);
                }

                configure(builder);

                Costruisci la pipeline di richieste
                Application = costruttore. Build();
            }
            catch (eccezione ex)
            {
                Logger.ApplicationError(ex);

                se (! Options.WebHostOptions.CaptureStartupErrors)
                {
                    getta;
                }

                var showDetailedErrors = HostingEnvironment.IsDevelopment() || Options.WebHostOptions.DetailedErrors;

                applicazione = ErrorPageBuilder.BuildErrorPageApplication(HostingEnvironment.ContentRootFileProvider, Logger, showDetailedErrors, es);
            }

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

            await Server.StartAsync(httpApplication, cancellationToken);

            se (indirizza != nullo)
            {
                Foreach (Indirizzo VAR negli indirizzi)
                {
                    LifetimeLogger.ListeningOnAddress(indirizzo);
                }
            }

            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);
Il login del link ipertestuale è visibile.

Metodo di estensione WebHostBuilderExtensions

Fornisce un oggetto startupType per le chiamate IWebHostBuilder.

questo IWebHostBuilder hostBuilder
if (hostBuilder è ISupportsStartup supportaAvvio)
{
    return supportsStartup.UseStartup(startupType);
}
Il login del link ipertestuale è visibile.

GenericWebHostBuilder Metodo Privato GenericWebHostBuilder

Istanzia dinamicamente il nostro oggetto Startup:

Istanza ?? = AttivatorUtilities.CreateInstance(nuovo HostServiceProvider(webHostBuilderContext), startupType);
contesto. Proprietà[_startupKey] = istanza;
Cerca il metodo ConfigureServices

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

internamente statico ConfigureServicesBuilder FindConfigureServicesDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Tipo startupType, stringa NomeAmbiente)
        {
            var servicesMethod = FindMethod(startupType, "Configure{0}Services", environmentName, typeof(IServiceProvider), required: false)
                ?? FindMethod(startupType, "Configure{0}Services", environmentName, typeof(void), required: false);
            return new ConfigureServicesBuilder(servicesMethod);
Cerca il metodo ConfigureContainer

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

internamente statico ConfigureContainerBuilder FindConfigureContainerDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Tipo startupType, stringa NomeAmbiente)
        {
            var configureMethod = FindMethod(startupType, "Configure{0}Container", environmentName, typeof(void), required: false);
            return new ConfigureContainerBuilder(configureMethod);
        }
Cerca il metodo Configure

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

ConfigureBuilder statico interno FindConfigureDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Type startupType, stringa environmentName)
{
    var configureMethod = FindMethod(startupType, "Configure{0}", environmentName, typeof(void), required: true)!;
    return new ConfigureBuilder(configureMethod);
}
Chiamato dal metodo Build di ConfigureBuilder, il codice sorgente è il seguente:

classe privata ConfigureBuilder
        {
            ConfigureBuilder pubblico (MethodInfo configure)
            {
                MethodInfo = configurare;
            }

            pubblico MethodInfo MethodInfo { get; }

            Build d'azione pubblica<IApplicationBuilder> (istanza oggetto)
            {
                return (applicationBuilder) => Invoke(istanza, applicationBuilder);
            }

            private void Invoke(object instance, IApplicationBuilder builder)
            {
                var serviceProvider = builder. Servizi Applicazioni;
                var parameterInfos = MethodInfo.GetParameters();
                var parameters = new object[parameterInfos.Length];
                per (var index = 0; indice < parametro Infos.Length; Indice++)
                {
                    var parameterInfo = parameterInfos[index];
                    if (parameterInfo.ParameterType == typeof(IApplicationBuilder))
                    {
                        parametri[indice] = costruttore;
                    }
                    altrimenti
                    {
                        prova
                        {
                            parametri[indice] = servizioFornitore.GetRequiredService(parameterInfo.ParameterType);
                        }
                        catch (eccezione ex)
                        {
                            throw new InvalidOperationException(
                                Resources.FormatMiddlewareFilter_ServiceResolutionFail(
                                    parameterInfo.ParameterType.NomeCompleto,
                                    parameterInfo.Name,
                                    MethodInfo.Name,
                                    MethodInfo.DichiaringType.NomeCompleto),
                                es;
                        }
                    }
                }
                MethodInfo.Invoke(istanza, parametri);
            }
        }
Metodo di esecuzione

Indirizzo del metodo di estensione HostingAbstractionsHostExtensions:

Il login del link ipertestuale è visibile.


Alla fine chiama:

/// <summary>
        Esegue un'applicazione e restituisce un Task che si completa solo quando il token viene attivato o si attiva la spegne.
        /// </summary>
        <param name="host">La <vedi cref="IHost"/> da eseguire.</param>
        <param name="token">Il token che attiva lo spegnimento (shutdown).</param>
        <returns>Il <vedi cref="Task"/> che rappresenta l'operazione asincrona.</returns>
        Task RunAsync pubblica statica e asincrona (questo host IHost, token CancellationToken = default)
        {
            prova
            {
                Aspetta l'ospite. StartAsync(token). ConfigureAwait(false);

                Aspetta l'ospite. WaitForShutdownAsync(token). ConfigureAwait(false);
            }
            finalmente
            {
                if (host is IAsyncDisposable asyncDisposable)
                {
                    await asyncDisposable.DisposeAsync(). ConfigureAwait(false);
                }
                altrimenti
                {
                    conduttore. Dispose();
                }

            }
        }
In precedenza, quando costruivo un servizio, mi registravo al servizio IHost, e il codice è il seguente:

servizi. <IHost>AddSingleton(_ =>
            {
                torna nuovo Internal.Host(_appServices,
                    _appServices.GetRequiredService<IHostApplicationLifetime>(),
                    _appServices.GetRequiredService<ILogger<Internal.Host>>(),
                    _appServices.GetRequiredService<IHostLifetime>(),
                    _appServices.GetRequiredService<IOptions<HostOptions>>());
            });
Metodo StartAsync

Indirizzo:Il login del link ipertestuale è visibile.

pubblico async Task StartAsync(CancellationToken cancellationToken = default)
        {
            _logger. Iniziale();

            usando 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 in _hostedServices)
            {
                // Fire IHostedService.Start
                await hostedService.StartAsync(combinedCancellationToken). ConfigureAwait(false);

                if (hostedService è BackgroundService backgroundService)
                {
                    _ = HandleBackgroundException(backgroundService);
                }
            }

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

            _logger. Iniziato();
        }
(Fine)




Precedente:Riferimenti di arrivo tardi
Prossimo:Errore .NET Core in Linux Pacchetto applicativo di elaborazione di fallimento
Pubblicato il 2021-9-22 20:45:12 |
Impara a imparare...
Disconoscimento:
Tutto il software, i materiali di programmazione o gli articoli pubblicati dalla Code Farmer Network sono destinati esclusivamente all'apprendimento e alla ricerca; I contenuti sopra elencati non devono essere utilizzati per scopi commerciali o illegali, altrimenti gli utenti dovranno sostenere tutte le conseguenze. Le informazioni su questo sito provengono da Internet, e le controversie sul copyright non hanno nulla a che fare con questo sito. Devi eliminare completamente i contenuti sopra elencati dal tuo computer entro 24 ore dal download. Se ti piace il programma, ti preghiamo di supportare software autentico, acquistare la registrazione e ottenere servizi autentici migliori. In caso di violazione, vi preghiamo di contattarci via email.

Mail To:help@itsvse.com