Révision:
Commencez par attacher l’adresse open source ASP.NET Core GitHub
La connexion hyperlientérée est visible.
La connexion hyperlientérée est visible.
Après avoir créé un nouveau projet ASP.NET Core 3.1, le code du programme est le suivant :
Nous avons approfondi le code d’entrée combiné au code source de GitHub.
Code hôte :La connexion hyperlientérée est visible.
Méthode CreateDefaultBuilder
Ici, nous instancions un objet HostBuilder, qui hérite d’IHostBuilder, et ajoutons des délégués définis par le système, tels que :appsettings.json, appsettings. {env. EnvironnementName}.json fichier de configuration, qui reviendra finalement : interface IHostBuilder.
Code HostBuilder :La connexion hyperlientérée est visible.
La méthode Build sera finalement appelée.
Build public IHost ()
{ si (_hostBuilt) { lancer un nouveau InvalidOperationException(SR. BuildCalled) ; } _hostBuilt = vrai ;
BuildHostConfiguration() ; CreateHostingEnvironment() ; CreateHostBuilderContext() ; BuildAppConfiguration() ; CreateServiceProvider() ;
retour _appServices.GetRequiredService<IHost>() ;
} Méthode BuildHostConfiguration
_hostConfiguration privé d’IConfiguration ; IConfigurationBuilder configBuilder = new ConfigurationBuilder() Appelez le délégué pour ajouter la configuration à son tour
Méthode CreateHostingEnvironment
Hébergement privé _hostingEnvironment ; _hostingEnvironment = nouvel Environnement d’Hébergement()
{ ApplicationName = _hostConfiguration[HostDefaults.ApplicationKey], EnvironnementName = _hostConfiguration[HostDefaults.EnvironmentKey] ?? Environnements.Production, ContentRootPath = ResolveContentRootPath(_hostConfiguration[HostDefaults.ContentRootKey], AppContext.BaseDirectory), }; Méthode CreateHostBuilderContext
privé HostBuilderContext _hostBuilderContext ; _hostBuilderContext = nouveau HostBuilderContext(Properties)
{ HôteEnvironnement = _hostingEnvironment, Configuration = _hostConfiguration }; Méthode BuildAppConfiguration
Réintégrer les informations de configuration
IConfigurationBuilder configBuilder = new ConfigurationBuilder() . SetBasePath(_hostingEnvironment.ContentRootPath) . AddConfiguration(_hostConfiguration, shouldDisposeConfiguration : true) ; _appConfiguration = configBuilder.Build() ; _hostBuilderContext.Configuration = _appConfiguration ; Méthode CreateServiceProvider
var services = nouvelle ServiceCollection() ; Enregistrer un service, appeler un délégué, et ajouter un service défini par l’utilisateur.
Méthode d’extension GenericHostBuilderExtensions
La connexion hyperlientérée est visible.
Méthode d’extension ConfigureWebHost
Pour enregistrer GenericWebHostService en tant que service backend :
constructeur. ConfigureServices((context, services) = > services. AddHostedService<GenericWebHostService>()) ; Code GenericWebHostService :La connexion hyperlientérée est visible.
Task StartAsync asynchrone public (CancellationToken cancellationToken) { HostingEventSource.Log.HostStart() ;
var serverAddressesFeature = Server.Features.Get<IServerAddressesFeature>() ; var addresses = serverAddressesFeature ?. Adresses ; si (adresses != null && !adreses. IsReadOnly & & adresses. Compte == 0) { var urls = Configuration[WebHostDefaults.ServerUrlsKey] ; if ( !string. IsNullOrEmpty(urls)) { FonctionnalitéAdresseServeurT ! PreferHostingUrls = WebHostUtilities.ParseBool(Configuration, WebHostDefaults.PreferHostingUrlsKey) ;
foreach (valeur var en URLs. Split(' ; ', ChainSplitOptions.RemoveEmptyEntries »)) { adresses. Ajouter(valeur) ; } } }
DemandeDélégué ? application = nul ;
essaie { var configure = Options.ConfigureApplication ;
if (configure == null) { throw new InvalidOperationException($"No application configured. Veuillez spécifier une application via IWebHostBuilder.UseStartup, IWebHostBuilder.Configure, ou spécifier l’assembleur de démarrage via {nameof(WebHostDefaults.StartupAssemblyKey)} dans le configuration de l’hébergeur web. ») ; }
var builder = ApplicationBuilderFactory.CreateBuilder(Server.Features) ;
foreach (var filter dans StartupFilters.Reverse()) { configurer = filtre. Configure(configure) ; }
configure(builder) ;
Construire le pipeline de requêtes Application = constructeur. Build() ; } catch (Exception ex) { Logger.ApplicationError(ex) ;
si ( ! Options.WebHostOptions.CaptureStartupErrors) { lancer ; }
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) ;
si (addresses != null) { foreach (adresse var dans les adresses) { LifetimeLogger.ListeningOnAddress (adresse) ; } }
if (Logger.IsEnabled(LogLevel.Debug)) { foreach (var assembly dans Options.WebHostOptions.GetFinalHostingStartupAssemblies()) { Logger.StartupAssemblyLoaded (assemblage) ; } }
if (Options.HostingStartupExceptions != null) { foreach (var exception dans Options.HostingStartupExceptions.InnerExceptions) { Logger.HostingStartupAssemblyError(exception) ; } } }
var webhostBuilder = new GenericWebHostBuilder(builder, webHostBuilderOptions) ; La connexion hyperlientérée est visible.
Méthode d’extension WebHostBuilderExtensions
Fournit un objet StartupType pour les appels IWebHostBuilder.
ce IWebHostBuilder hôteConstructeur if (hostBuilder est ISupportsStartup supporteDémarrage)
{ return supportsStartup.UseStartup(startType) ;
} La connexion hyperlientérée est visible.
GenericWebHostBuilder Méthode privée GenericWebHostBuilder
Instanciez dynamiquement notre objet Startup :
Instance ?? = ActivatorUtilities.CreateInstance (nouveau HostServiceProvider(webHostBuilderContext), startType ; Contexte. Propriétés[_startupKey] = instance ; Cherchez la méthode ConfigureServices
var configureServicesBuilder = StartupLoader.FindConfigureServicesDelegate(startupType, context. HôteEnvironnement.NomEnvironnement) ; var configureServices = configureServicesBuilder.Build(instance) ;
ConfigureServicesBuilder statique interne FindConfigureServicesDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Type startupType, chaîne environnementNom) { var servicesMethod = FindMethod(startupType, « Configure{0}Services », environmentName, typeof(IServiceProvider), required : false) ?? FindMethod (startType, « Configure{0}Services », environnementName , typeof(void), required : false) ; return new ConfigureServicesBuilder(servicesMethod) ; Cherchez la méthode ConfigureContainer
var configureContainerBuilder = StartupLoader.FindConfigureContainerDelegate(startupType, context. HôteEnvironnement.NomEnvironnement) ;
ConfigureContainerBuilder statique interne FindConfigureContainerDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Type startupType, chaîne environnementNom) { var configureMethod = FindMethod(startupType, « Configure{0}Container », environmentName, typeof(void), required : false) ; return new ConfigureContainerBuilder(configureMethod) ; } Cherchez la méthode Configure
configureBuilder = StartupLoader.FindConfigureDelegate(startupType, context. HôteEnvironnement.NomEnvironnement) ;
ConfigureBuilder statique interne FindConfigureDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Type startupType, string environmentName)
{ var configureMethod = FindMethod(startupType, « Configure{0} », environmentName, typeof(void), required : true) !; return new ConfigureBuilder(configureMethod) ;
} Appelé par la méthode Build de ConfigureBuilder, le code source est le suivant :
classe privée ConfigureBuilder { public ConfigureBuilder(MethodInfo configure) { MethodInfo = configure ; }
public MethodInfo MethodInfo { get ; }
Build d’action publique<IApplicationBuilder> (instance d’objet) { return (applicationBuilder) => Invoke(instance, applicationBuilder) ; }
void privé Invoke(instance d’objet, IApplicationBuilder builder) { var serviceProvider = builder. Services d’application ; var parameterInfos = MethodInfo.GetParameters() ; var paramètres = new object[parameterInfos.Length] ; pour (var index = 0 ; index < parameterInfos.Length ; index++) { var parameterInfo = parameterInfos[index] ; if (parameterInfo.ParameterType == typeof(IApplicationBuilder)) { paramètres[index] = constructeur ; } sinon { essaie { paramètres[index] = serviceFourniseur.GetRequiredService(parameterInfo.ParameterType) ; } catch (Exception ex) { lancer un nouveau InvalidOperationException( Resources.FormatMiddlewareFilter_ServiceResolutionFail( parameterInfo.ParameterType.NomComplet, parameterInfo.Name, MethodInfo.Name, MethodInfo.DéclaringType.NomComplet), ex ; } } } MethodInfo.Invoke(instance, parameters) ; } } Méthode de la course
Adresse de la méthode d’extension HostingAbstractionsHostExtensions :
La connexion hyperlientérée est visible.
Finalement appelle :
/// <summary> Exécute une application et renvoie une tâche qui ne s’achève que lorsque le jeton est déclenché ou que l’arrêt est déclenché. /// </summary> <param name="host">Le <voir cref="IHost"/> à exécuter.</param> <param name="token">Le jeton déclenche l’arrêt.</param> <returns>Le <voir cref="Task"/> qui représente l’opération asynchrone.</returns> Task RunAsync statique public async (this IHost host, token CancellationToken = default) { essaie { Attends l’hôte. StartAsync (jeton). ConfigureAwait (faux) ;
Attends l’hôte. WaitForShutdownAsync (token). ConfigureAwait (faux) ; } Enfin { if (l’hôte est IAsyncDisposable asyncDisposable) { await asyncDisposable.DisposeAsync(). ConfigureAwait (faux) ; } sinon { Hôte. Dispose() ; }
} } Auparavant, lorsque je développais un service, je m’inscrivais au service IHost, et le code est le suivant :
services. <IHost>AddSingleton(_ => { retour au nouvel Internal.Host(_appServices, _appServices.GetRequiredService<IHostApplicationLifetime>(), _appServices.GetRequiredService<ILogger<Internal.Host>>(), _appServices.GetRequiredService<IHostLifetime>(), _appServices.GetRequiredService<IOptions<HostOptions>>()) ; }); Méthode StartAsync
Adresse:La connexion hyperlientérée est visible.
public async Task StartAsync (CancellationToken cancellationToken = default) { _logger. Débutant() ;
using var combinedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _applicationLifetime.ApplicationStopping) ; CancellationToken combinéAnnulationToken = combinéCancellationSourceSource.Token ;
await _hostLifetime.WaitForStartAsync (combinedCancellationToken). ConfigureAwait (faux) ;
combinedCancellationToken.ThrowIfCancellationRequested() ; _hostedServices = Services.GetService<IEnumerable<IHostedService>>() ;
foreach (IHostedService hébergé, Service en _hostedServices) { // Fire IHostedService.Start await hostedService.StartAsync(combinedCancellationToken). ConfigureAwait (faux) ;
if (hostedService est BackgroundService backgroundService) { _ = HandleBackgroundException (backgroundService) ; } }
// Fire IHostApplicationLifetime.Started _applicationLifetime.NotifyStarted() ;
_logger. Commencé () ; } (Fin)
|