Recensione:
Inizia allegando l'indirizzo open source ASP.NET Core GitHub
Il login del link ipertestuale è visibile.
Il login del link ipertestuale è visibile.
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)
|