Αναθεώρηση:
Ξεκινήστε επισυνάπτοντας τη διεύθυνση ανοιχτού κώδικα ASP.NET Core GitHub
Η σύνδεση με υπερσύνδεσμο είναι ορατή.
Η σύνδεση με υπερσύνδεσμο είναι ορατή.
Μετά τη δημιουργία ενός νέου έργου ASP.NET Core 3.1, ο κώδικας του προγράμματος έχει ως εξής:
Κάναμε μια βαθιά βουτιά στον κωδικό εισόδου σε συνδυασμό με τον πηγαίο κώδικα του GitHub.
Κωδικός κεντρικού υπολογιστή:Η σύνδεση με υπερσύνδεσμο είναι ορατή.
Μέθοδος CreateDefaultBuilder
Εδώ δημιουργούμε ένα αντικείμενο HostBuilder, το οποίο κληρονομεί από το IHostBuilder, και προσθέτουμε αντιπροσώπους που ορίζονται από το σύστημα, όπως :appsettings.json, ρυθμίσεις εφαρμογών. {env. EnvironmentName}.json αρχείο διαμόρφωσης, το οποίο τελικά θα επιστρέψει: Διεπαφή IHostBuilder.
Κωδικός HostBuilder:Η σύνδεση με υπερσύνδεσμο είναι ορατή.
Η μέθοδος Build θα κληθεί τελικά.
δημόσιο IHost Build()
{ αν (_hostBuilt) { ρίξτε νέο InvalidOperationException(SR. BuildCalled); } _hostBuilt = αληθές;
BuildHostConfiguration(); CreateHostingEnvironment(); CreateHostBuilderContext(); BuildAppConfiguration(); CreateServiceProvider();
επιστροφή _appServices.GetRequiredService<IHost>();
} Μέθοδος BuildHostConfiguration
ιδιωτική _hostConfiguration απεικόνισης. IConfigurationBuilder configBuilder = νέο ConfigurationBuilder() Καλέστε τον πληρεξούσιο για να προσθέσετε ρύθμιση παραμέτρων με τη σειρά
Μέθοδος CreateHostingEnvironment
ιδιωτικό HostingEnvironment _hostingEnvironment; _hostingEnvironment = νέο HostingEnvironment()
{ ΌνομαΕφαρμογής = _hostConfiguration[HostDefaults.ApplicationKey], ΌνομαΠεριβάλλοντος = _hostConfiguration[HostDefaults.EnvironmentKey] ?? Περιβάλλοντα.Παραγωγή, ContentRootPath = ResolveContentRootPath(_hostConfiguration[HostDefaults.ContentRootKey], AppContext.BaseDirectory), }; Μέθοδος CreateHostBuilderContext
ιδιωτικό HostBuilderContext _hostBuilderContext; _hostBuilderContext = νέο HostBuilderContext(Ιδιότητες)
{ Περιβάλλον φιλοξενίας = _hostingEnvironment, Διαμόρφωση = _hostConfiguration }; Μέθοδος BuildAppConfiguration
Ενσωματώστε ξανά τις πληροφορίες διαμόρφωσης
IConfigurationBuilder configBuilder = νέο ConfigurationBuilder() . SetBasePath(_hostingEnvironment.ΔιαδρομήΡίζαςΠεριεχομένου) . AddConfiguration(_hostConfiguration, shouldDisposeConfiguration: true); _appConfiguration = configBuilder.Build(); _hostBuilderContext.Διαμόρφωση = _appConfiguration; Μέθοδος CreateServiceProvider
var services = νέα ServiceCollection(); Καταχωρήστε μια υπηρεσία, καλέστε έναν πληρεξούσιο και προσθέστε μια υπηρεσία που ορίζεται από το χρήστη.
Μέθοδος επέκτασης GenericHostBuilderExtensions
Η σύνδεση με υπερσύνδεσμο είναι ορατή.
Μέθοδος επέκτασης ConfigureWebHost
Για να καταχωρήσετε το GenericWebHostService ως υπηρεσία υποστήριξης:
οικοδόμος. ConfigureServices((context, services) => services. AddHostedService<GenericWebHostService>()); Κωδικός GenericWebHostService:Η σύνδεση με υπερσύνδεσμο είναι ορατή.
public async Task StartAsync(CancellationToken cancellationToken) { HostingEventSource.Log.HostStart();
var serverAddressesFeature = Server.Features.Get<IServerAddressesFeature>(); var addresses = serverAddressesFeature?. Διευθύνσεις; if (διευθύνσεις != null &&& !addresses. IsReadOnly & διευθύνσεις. Πλήθος == 0) { var urls = Διαμόρφωση[WebHostDefaults.ServerUrlsKey]; αν (!string. IsNullOrEmpty(urls)) { serverAddressesFeature!. PreferHostingUrls = WebHostUtilities.ParseBool(Διαμόρφωση, WebHostDefaults.PreferHostingUrlsKey);
foreach (τιμή var σε διευθύνσεις URL. Split('; ', StringSplitOptions.RemoveEmptyEntries)) { διευθύνσεις. Add(τιμή); } } }
ΑίτημαΑντιπρόσωπος; εφαρμογή = null;
Δοκιμάστε { var configure = Επιλογές.ΔιαμόρφωσηΕφαρμογή;
αν (διαμόρφωση == null) { ρίξτε νέο InvalidOperationException($"Δεν έχει ρυθμιστεί η εφαρμογή. Προσδιορίστε μια εφαρμογή μέσω των IWebHostBuilder.UseStartup, IWebHostBuilder.Configure ή καθορίζοντας τη συγκρότηση εκκίνησης μέσω του {nameof(WebHostDefaults.StartupAssemblyKey)} στο διαμόρφωση του κεντρικού υπολογιστή ιστού."); }
var builder = ApplicationBuilderFactory.CreateBuilder(Server.Features);
foreach (φίλτρο var στο StartupFilters.Reverse()) { configure = φίλτρο. Ρύθμιση παραμέτρων(διαμόρφωση); }
configure(κατασκευαστής);
Δημιουργία της διοχέτευσης αίτησης εφαρμογή = οικοδόμος. Build(); } αλιεύματα (Εξαίρεση π.χ.) { Logger.ApplicationError(π.χ.);
αν (! Options.WebHostOptions.CaptureStartupErrors) { ρίζω; }
var showDetailedErrors = HostingEnvironment.IsDevelopment() || Επιλογές.WebHostOptions.DetailedErrors;
εφαρμογή = ErrorPageBuilder.BuildErrorPageApplication(HostingEnvironment.ContentRootFileProvider, Καταγραφέας, showDetailedErrors, π.χ.); }
var httpApplication = νέα HostingApplication(application, Logger, DiagnosticListener, HttpContextFactory);
περιμένετε Server.StartAsync(httpApplication, cancellationToken);
if (διευθύνσεις != null) { foreach (διεύθυνση var στις διευθύνσεις) { LifetimeLogger.ListeningOnAddress(διεύθυνση); } }
αν (Logger.IsEnabled(LogLevel.Debug)) { foreach (var assembly στο Options.WebHostOptions.GetFinalHostingStartupAssemblies()) { Logger.StartupAssemblyLoaded(συναρμολόγηση); } }
αν (Options.HostingStartupExceptions != null) { foreach (εξαίρεση var στο Options.HostingStartupExceptions.InnerExceptions) { Logger.HostingStartupAssemblyError(εξαίρεση); } } }
var webhostBuilder = νέο GenericWebHostBuilder(κατασκευαστής, webHostBuilderOptions); Η σύνδεση με υπερσύνδεσμο είναι ορατή.
Μέθοδος επέκτασης WebHostBuilderExtensions
Παρέχει ένα αντικείμενο startupType για κλήσεις IWebHostBuilder.
αυτό το IWebHostBuilder hostBuilder if (το hostBuilder είναι ISupportsStartup supportsStartup)
{ return supportsStartup.UseStartup(startupType);
} Η σύνδεση με υπερσύνδεσμο είναι ορατή.
GenericWebHostBuilder Ιδιωτική μέθοδος GenericWebHostBuilder
Δημιουργήστε δυναμικά το αντικείμενο εκκίνησης:
παράδειγμα ?? = ActivatorUtilities.CreateInstance(νέο HostServiceProvider(webHostBuilderContext), startupType); πλαίσιο. Ιδιότητες[_startupKey] = στιγμιότυπο; Αναζητήστε τη μέθοδο ConfigureServices
var configureServicesBuilder = StartupLoader.FindConfigureServicesDelegate(startupType, context. HostingEnvironment.EnvironmentName); var configureServices = configureServicesBuilder.Build(instance);
εσωτερική στατική ConfigureServicesBuilder FindConfigureServicesDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Πληκτρολογήστε startupType, συμβολοσειρά environmentName) { var servicesMethod = FindMethod(startupType; "Configure{0}Services", environmentName, typeof(IServiceProvider); required: false) ?? FindMethod(startupType; "Configure{0}Services", environmentName, typeof(void), απαιτείται: false); επιστροφή νέου ConfigureServicesBuilder(servicesMethod); Αναζητήστε τη μέθοδο ConfigureContainer
var configureContainerBuilder = StartupLoader.FindConfigureContainerDelegate(startupType, context. HostingEnvironment.EnvironmentName);
εσωτερική στατική ConfigureContainerBuilder FindConfigureContainerDeleggate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Τύπος startupType, συμβολοσειρά environmentName) { var configureMethod = FindMethod(startupType, "Configure{0}Container", environmentName, typeof(void), απαιτείται: false); επιστροφή νέου ConfigureContainerBuilder(configureMethod); } Αναζητήστε τη μέθοδο Configure
configureBuilder = StartupLoader.FindConfigureDelegate(startupType, context. HostingEnvironment.EnvironmentName);
εσωτερική στατική ConfigureBuilder FindConfigureDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Τύπος startupType, συμβολοσειρά environmentName)
{ var configureMethod = FindMethod(startupType, "Configure{0}", environmentName, typeof(void), required: true)!; επιστροφή νέου ConfigureBuilder(configureMethod);
} Καλείται με τη μέθοδο Build του ConfigureBuilder, ο πηγαίος κώδικας είναι ο εξής:
ιδιωτική τάξη ConfigureBuilder { public ConfigureBuilder(Ρύθμιση παραμέτρων MethodInfo) { MethodInfo = διαμόρφωση; }
public MethodInfo MethodInfo { get; }
public Action<IApplicationBuilder> Build(παρουσία αντικειμένου) { return (applicationBuilder) => Invoke(instance, applicationBuilder); }
private void Invoke(παρουσία αντικειμένου, IApplicationBuilder builder) { var serviceProvider = οικοδόμος. Υπηρεσίες εφαρμογών; var parameterInfos = MethodInfo.GetParameters(); var παράμετροι = νέο αντικείμενο[parameterInfos.Length]; για (δείκτης var = 0; δείκτης < παράμετροςInfos.Length; ευρετήριο++) { var parameterInfo = parameterInfos[index]; if (parameterInfo.ParameterType == typeof(IApplicationBuilder)) { parameters[index] = οικοδόμος; } αλλιώς { Δοκιμάστε { παράμετροι[index] = serviceProvider.GetRequiredService(parameterInfo.ParameterType); } αλιεύματα (Εξαίρεση π.χ.) { ρίξε νέο InvalidOperationException( Resources.FormatMiddlewareFilter_ServiceResolutionFail( παράμετροςInfo.ParameterType.FullName, parameterInfo.Name, MethodInfo.Name, MethodInfo.DeclaringType.FullName), πρώην); } } } MethodInfo.Invoke(στιγμιότυπο, παράμετροι); } } Μέθοδος εκτέλεσης
Διεύθυνση μεθόδου επέκτασης HostingAbstractionsHostExtensions:
Η σύνδεση με υπερσύνδεσμο είναι ορατή.
Τελικά καλεί:
/// <summary> Εκτελεί μια εφαρμογή και επιστρέφει μια εργασία που ολοκληρώνεται μόνο όταν ενεργοποιείται το διακριτικό ή ενεργοποιείται ο τερματισμός λειτουργίας. /// </summary> <param name="host">Το <see cref="IHost"/> να εκτελεστεί.</param> <param name="token">Το διακριτικό για την ενεργοποίηση του τερματισμού λειτουργίας.</param> <returns>Το <see cref="Task"/> που αντιπροσωπεύει την ασύγχρονη λειτουργία.</returns> δημόσια στατική ασύγχρονη εργασία RunAsync(αυτός ο κεντρικός υπολογιστής IHost, διακριτικό CancellationToken = προεπιλογή) { Δοκιμάστε { περιμένουν τον οικοδεσπότη. StartAsync(διακριτικό). ConfigureAwait(false);
περιμένουν τον οικοδεσπότη. WaitForShutdownAsync(διακριτικό). ConfigureAwait(false); } Τελικά { if (ο κεντρικός υπολογιστής είναι IAsyncDisposable asyncDisposable) { wait asyncDisposable.DisposeAsync(). ConfigureAwait(false); } αλλιώς { οικοδεσπότης. Απόρριψη(); }
} } Προηγουμένως, όταν έφτιαχνα μια υπηρεσία, εγγραφόμουν στην υπηρεσία IHost και ο κωδικός είναι ο εξής:
υπηρεσιών. AddSingleton<IHost>(_ => { επιστροφή νέου Internal.Host(_appServices, _appServices.GetRequiredService<IHostApplicationLifetime>(), _appServices.GetRequiredService<ILogger<Internal.Host>>(), _appServices.GetRequiredService<IHostLifetime>(), _appServices.GetRequiredService<IOptions<HostOptions>>()); }); Μέθοδος StartAsync
Διεύθυνση:Η σύνδεση με υπερσύνδεσμο είναι ορατή.
public async Task StartAsync(CancellationToken cancellationToken = προεπιλογή) { _logger. Έναρξη();
χρησιμοποιώντας var combinedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _applicationLifetime.ApplicationStopping); CancellationToken combinedCancellationToken = combinedCancellationTokenSource.Token;
περιμένετε _hostLifetime.WaitForStartAsync(combinedCancellationToken). ConfigureAwait(false);
combinedCancellationToken.ThrowIfCancellationRequested(); _hostedServices = Services.GetService<IEnumerable<IHostedService>>();
foreach (IHostedService hostedService in _hostedServices) { Πυρκαγιά IHostedService.Έναρξη await hostedService.StartAsync(combinedCancellationToken). ConfigureAwait(false);
if (hostedService είναι BackgroundService backgroundService) { _ = HandleBackgroundException(backgroundService); } }
Πυρκαγιά IHostApplicationLifetime.Started _applicationLifetime.NotifyStarted();
_logger. Started(); } (Τέλος)
|