Přezkoumání:
Začněte připojením open source adresy ASP.NET Core GitHub
Přihlášení k hypertextovému odkazu je viditelné.
Přihlášení k hypertextovému odkazu je viditelné.
Po vytvoření nového projektu ASP.NET Core 3.1 je kód programu následující:
Důkladně jsme se ponořili do vstupního kódu v kombinaci se zdrojovým kódem GitHubu.
Kód hostitele:Přihlášení k hypertextovému odkazu je viditelné.
Metoda CreateDefaultBuilder
Zde instancujeme objekt HostBuilder, který dědí z IHostBuilderu, a přidáváme systémově definované delegáty, jako jsou :appsettings.json, appsettings. {env. EnvironmentName}.json konfigurační soubor, který nakonec vrátí: rozhraní IHostBuilder.
Kód HostBuilderu:Přihlášení k hypertextovému odkazu je viditelné.
Metoda Build bude nakonec vyvolána.
public IHost Build()
{ pokud (_hostBuilt) { vyhodit nový InvalidOperationException(SR. BuildCalled); } _hostBuilt = pravda;
BuildHostConfiguration(); CreateHostingEnvironment(); CreateHostBuilderContext(); BuildAppConfiguration(); CreateServiceProvider();
return _appServices.GetRequiredService<IHost>();
} Metoda BuildHostConfiguration
soukromý _hostConfiguration IConfigurace; IConfigurationBuilder configBuilder = nový ConfigurationBuilder() Zavolejte delegáta, aby následně přidal konfiguraci
Metoda CreateHostingEnvironment
soukromé HostingEnvironment _hostingEnvironment; _hostingEnvironment = nový HostingEnvironment()
{ ApplicationName = _hostConfiguration[HostDefaults.ApplicationKey], EnvironmentName = _hostConfiguration[HostDefaults.EnvironmentKey] ?? Prostředí. Produkce, ContentRootPath = ResolveContentRootPath(_hostConfiguration[HostDefaults.ContentRootKey], AppContext.BaseDirectory), }; Metoda CreateHostBuilderContext
soukromý HostBuilderContext _hostBuilderContext; _hostBuilderContext = nový HostBuilderContext(Properties)
{ HostingEnvironment = _hostingEnvironment, Konfigurace = _hostConfiguration }; Metoda BuildAppConfiguration
Znovu integrujte konfigurační informace
IConfigurationBuilder configBuilder = nový ConfigurationBuilder() . SetBasePath(_hostingEnvironment.ContentRootPath) . AddConfiguration(_hostConfiguration, shouldDisposeConfiguration: true); _appConfiguration = configBuilder.Build(); _hostBuilderContext.Konfigurace = _appConfiguration; Metoda CreateServiceProvider
var services = nová ServiceCollection(); Zaregistrujte službu, zavolejte delegáta a přidejte uživatelem definovanou službu.
Metoda rozšíření GenericHostBuilderExtensions
Přihlášení k hypertextovému odkazu je viditelné.
Metoda rozšíření ConfigureWebHost
Pro registraci GenericWebHostService jako backendové služby:
stavitel. ConfigureServices((context, services) => services. AddHostedService<GenericWebHostService>()); GenericWebHostService kód:Přihlášení k hypertextovému odkazu je viditelné.
public async Task StartAsync(CancellationToken cancellationToken) { HostingEventSource.Log.HostStart();
var serverAddressesFeature = Server.Features.Get<IServerAddressesFeature>(); var addresses = serverAddressesFeature?. Adresy; if (adresy != null & !adresy. IsReadOnly & addresses. Počet == 0) { var urls = Configuration[WebHostDefaults.ServerUrlsKey]; if (!string. IsNullOrEmpty(urls)) { serverAddressesFeature!. PreferHostingUrls = WebHostUtilities.ParseBool(Configuration, WebHostDefaults.PreferHostingUrlsKey);
Foreach (hodnota VAR v URL. Split('; ', StringSplitOptions.RemoveEmptyEntries)) { adresy. Add(value); } } }
RequestDelege? aplikace = null;
zkus { var configure = Options.ConfigureApplication;
if (configure == null) { throw new InvalidOperationException($"Žádná aplikace není nakonfigurována. Zadejte prosím aplikaci pomocí IWebHostBuilder.UseStartup, IWebHostBuilder.Configure, nebo zadejte startovací assembler pomocí {nameof(WebHostDefaults.StartupAssemblyKey)} v konfigurace webového hostitele."); }
var builder = ApplicationBuilderFactory.CreateBuilder(Server.Features);
foreach (var filter in StartupFilters.Reverse()) { configure = filtr. konfigurovat (konfigurovat); }
configure(builder);
Vytvořte pipeline požadavků aplikace = stavitel. build(); } chytit (Výjimka ex) { Logger.ApplicationError(ex);
pokud (! Options.WebHostOptions.CaptureStartupErrors) { hod; }
var showDetailedErrors = HostingEnvironment.IsDevelopment() || Options.WebHostOptions.DetailedErrors;
application = ErrorPageBuilder.BuildErrorPageApplication(HostingEnvironment.ContentRootFileProvider, Logger, showDetailedErrors, ex); }
var httpApplication = nový HostingApplication(application, Logger, DiagnosticListener, HttpContextFactory);
await Server.StartAsync(httpApplication, cancellationToken);
if (adresuje != null) { foreach (VAR adresa v adresách) { LifetimeLogger.ListeningOnAddress(adresa); } }
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 = nový GenericWebHostBuilder(builder, webHostBuilderOptions); Přihlášení k hypertextovému odkazu je viditelné.
Metoda rozšíření WebHostBuilderExtensions
Poskytuje objekt startupType pro volání IWebHostBuilder.
tento IWebHostBuilder hostBuilder pokud (hostBuilder is ISupportsStartup supportsStartup)
{ return supportsStartup.UseStartup(startupType);
} Přihlášení k hypertextovému odkazu je viditelné.
GenericWebHostBuilder Private Method GenericWebHostBuilder
Dynamicky instancujte náš Startup objekt:
instance ?? = ActivatorUtilities.CreateInstance (nový HostServiceProvider(webHostBuilderContext), startType); Kontext. Vlastnosti[_startupKey] = instance; Hledejte metodu ConfigureServices
var configureServicesBuilder = StartupLoader.FindConfigureServicesDelegate(startupType, context. HostingEnvironment.EnvironmentName); var configureServices = configureServicesBuilder.Build(instance);
internal static ConfigureServicesBuilder FindConfigureServicesDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Zadejte startupType, string environmentName) { 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); Hledejte metodu ConfigureContainer
var configureContainerBuilder = StartupLoader.FindConfigureContainerDelegate(startupType, context. HostingEnvironment.EnvironmentName);
internal static ConfigureContainerBuilder FindConfigureContainerDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Zadejte startupType, string environmentName) { var configureMethod = FindMethod(startupType, "Configure{0}Container", environmentName, typeof(void), required: false); return new ConfigureContainerBuilder(configureMethod); } Hledejte metodu Configure
configureBuilder = StartupLoader.FindConfigureDelegate(startupType, context. HostingEnvironment.EnvironmentName);
internal static ConfigureBuilder FindConfigureDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Zadejte startupType, string environmentName)
{ var configureMethod = FindMethod(startupType, "Configure{0}", environmentName, typeof(void), required: true)!; return new ConfigureBuilder(configureMethod);
} Zdrojový kód je volán metodou Build v ConfigureBuilder a je následující:
soukromá třída ConfigureBuilder { public ConfigureBuilder(MethodInfo configure) { MethodInfo = konfigurovat; }
public MethodInfo MethodInfo { get; }
public<IApplicationBuilder> Action Build (instance objektu) { return (applicationBuilder) => Invoke(instance, applicationBuilder); }
private void Invoke(instance objektu, IApplicationBuilder builder) { var serviceProvider = builder. ApplicationServices; var parameterInfos = MethodInfo.GetParameters(); parametr var = nový objekt[parameterInfos.Length]; pro (var index = 0; index < parametrInfos.Length; index++) { var parameterInfo = parameterInfos[index]; if (parameterInfo.ParameterType == typeof(IApplicationBuilder)) { parametry[index] = stavitel; } jinak { zkus { parameters[index] = serviceProvider.GetRequiredService(parameterInfo.ParameterType); } chytit (Výjimka ex) { vyhodit novou InvalidOperationException( Resources.FormatMiddlewareFilter_ServiceResolutionFail( parameterInfo.ParameterType.FullName, parameterInfo.Name, MethodInfo.Name, MethodInfo.DeclaringType.FullName), ex); } } } MethodInfo.Invoke(instance, parametry); } } Metoda běhu
Adresa metody rozšíření HostingAbstractionsHostExtensions:
Přihlášení k hypertextovému odkazu je viditelné.
Nakonec zavolá:
/// <summary> Spustí aplikaci a vrátí úkol, který se dokončí pouze tehdy, když je token spuštěn nebo vypnutí. /// </summary> <název parametru="host"><Viz cref="IHost"/> běžet.</param> <název parametru="token">Token pro spuštění vypnutí.</param> <returns><viz cref="Task"/> představuje asynchronní operaci.</returns> public static async Task RunAsync (tento IHost host, CancellationToken token = výchozí) { zkus { Čekejte na hostitele. StartAsync(token). ConfigureAwait(false);
Čekejte na hostitele. WaitForShutdownAsync(token). ConfigureAwait(false); } Konečně { if (host is IAsyncDisposable asyncDisposable) { await asyncDisposable.DisposeAsync(). ConfigureAwait(false); } jinak { hostitel. Dispose(); }
} } Dříve, když jsem budoval službu, registroval jsem se do služby IHost a kód byl následující:
Služby. AddSingleton<IHost>(_ => { return new Internal.Host(_appServices, _appServices.GetRequiredService<IHostApplicationLifetime>(), _appServices.GetRequiredService<ILogger<Internal.Host>>(), _appServices.GetRequiredService<IHostLifetime>(), _appServices.GetRequiredService<IOptions<HostOptions>>()); }); Metoda StartAsync
Adresa:Přihlášení k hypertextovému odkazu je viditelné.
public async Task StartAsync(CancellationToken cancellationToken = výchozí) { _logger. Starting();
použitím 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 v _hostedServices) { // Fire IHostedService.Start await hostedService.StartAsync (combinedCancellationToken). ConfigureAwait(false);
if (hostedService is BackgroundService backgroundServiceServices) { _ = HandleBackgroundException(backgroundService); } }
// Fire IHostApplicationLifetime.Started _applicationLifetime.NotifyStarted();
_logger. Started(); } (Konec)
|