Revisar:
Comece anexando o endereço open source ASP.NET Core do GitHub
O login do hiperlink está visível.
O login do hiperlink está visível.
Após criar um novo projeto ASP.NET Core 3.1, o código do programa é o seguinte:
Aprofundamos o código de entrada combinado com o código-fonte do GitHub.
Código do Hospedeiro:O login do hiperlink está visível.
Método CreateDefaultBuilder
Aqui instanciamos um objeto HostBuilder, que herda do IHostBuilder, e adicionamos delegados definidos pelo sistema, como :appsettings.json, appsettings. {env. EnvironmentName}.json arquivo de configuração, que eventualmente retornará: interface IHostBuilder.
Código HostBuilder:O login do hiperlink está visível.
O método Build será eventualmente chamado.
Build pública IHost()
{ se (_hostBuilt) { lançar um novo InvalidOperationException(SR. BuildCalled); } _hostBuilt = verdadeiro;
BuildHostConfiguration(); CriarAmbienteDeHospedagem(); CriarHostConstrutorContexto(); BuildAppConfiguration(); CreateServiceProvider();
retorno _appServices.ReceberRequisitoServiço<IHost>();
} Método BuildHostConfiguration
_hostConfiguration privada de Iconfiguração; IConfigurationBuilder configBuilder = novo ConfigurationBuilder() Chame o delegado para adicionar configuração em sua vez
Método CreateHostingEnvironment
privado HostingEnvironment _hostingEnvironment; _hostingEnvironment = novo Ambiente de Hospedagem()
{ NomeAplicação = _hostConfiguration[PadrãoHostPadrão.ChaveAplicação], NomeAmbiente = _hostConfiguration[HostDefaults.EnvironmentKey] ?? Ambientes.Produção, ContentRootPath = ResolveContentRootPath(_hostConfiguration[HostDefaults.ContentRootKey], AppContext.BaseDirectory), }; Método CreateHostBuilderContext
privado HostBuilderContext _hostBuilderContext; _hostBuilderContext = novo HostBuilderContext(Properties)
{ HostingEnvironment = _hostingEnvironment, Configuração = _hostConfiguration }; Método BuildAppConfiguration
Integre novamente as informações de configuração
IConfigurationBuilder configBuilder = novo ConfigurationBuilder() . SetBasePath(_hostingEnvironment.ContentRootPath) . AddConfiguration(_hostConfiguration, shouldDisposeConfiguration: true); _appConfiguration = configBuilder.Build(); _hostBuilderContext.Configuração = _appConfiguration; Método CreateServiceProvider
var services = nova ServiceCollection(); Registre um serviço, chame um delegado e adicione um serviço definido pelo usuário.
Método de extensão GenericHostBuilderExtensions
O login do hiperlink está visível.
Método de extensão ConfigureWebHost
Para registrar o GenericWebHostService como um serviço backend:
construtor. ConfigureServices((contexto, serviços) = > serviços. AddHostedService<GenericWebHostService>()); GenericWebHostService Código:O login do hiperlink está visível.
Tarefa pública assíncrona StartAsync(CancellationToken cancellationToken) { HostingEventSource.Log.HostStart();
var serverAddressesFeature = Server.Features.Get<IServerAddressesFeature>(); var endereços = servidorEndereçosFuncionalidade?. Endereços; se (endereços != null && !endereços. Endereços IsReadOnly & & Only. Contagem == 0) { var urls = Configuration[WebHostDefaults.ServerUrlsKey]; if (!string. IsNullOrEmpty(urls)) { FuncionalidadeEndereçosDo Servidor!. PreferHostingUrls = WebHostUtilities.ParseBool(Configuration, WebHostDefaults.PreferHostingUrlsKey);
Foreach (valor var em URLs. Split('; ', StringSplitOptions.RemoveEmptyNtries)) { endereços. Somar (valor); } } }
SolicitarDelegar? aplicação = nulo;
tente { var configure = Options.ConfigureApplication;
if (configure == null) { lançar um novo InvalidOperationException($"No application configured. Por favor, especifique uma aplicação via IWebHostBuilder.UseStartup, IWebHostBuilder.Configure ou especificando o assembly de inicialização via {nameof(WebHostDefaults.StartupAssemblyKey)} no configuração de hospedagem."); }
var builder = ApplicationBuilderFactory.CreateBuilder(Server.Features);
foreach (var filter em StartupFilters.Reverse()) { configure = filtro. Configure(configure); }
configure(builder);
Construir o pipeline de requisições aplicação = construtor. Build(); } captura (exceção ex) { Logger.ApplicationError(ex);
se (! Options.WebHostOptions.CaptureStartupErrors) { arremesse; }
var showDetailedErrors = HostingEnvironment.IsDevelopment() || Options.WebHostOptions.DetailedErrors;
aplicação = ConstrutorPáginaErro.BuildPáginaAplicaçãoErro(AmbienteDeHospedagem.FornecedorRaiz do Conteúdo, Logger, mostrarErrosDetalhados, ex); }
var httpApplication = new HostingApplication(application, Logger, DiagnosticListener, HttpContextFactory);
await Server.StartAsync(httpApplication, cancellationToken);
se (endereços != nulo) { Foreach (endereço var em endereços) { LifetimeLogger.ListeningOnAddress(endereço); } }
if (Logger.IsEnabled(LogLevel.Debug)) { foreach (var assembly em Options.WebHostOptions.GetFinalHostingStartupAssemblies()) { Logger.StartupAssemblyLoaded(assembly); } }
if (Options.HostingStartupExceptions != null) { foreach (var exception em Options.HostingStartupExceptions.InnerExceptions) { Logger.HostingStartupAssemblyError(exception); } } }
var webhostBuilder = novo GenericWebHostBuilder(builder, webHostBuilderOptions); O login do hiperlink está visível.
Método de extensão WebHostBuilderExtensions
Fornece um objeto startupType para chamadas IWebHostBuilder.
este IWebHostBuilder hostBuilder if (hostBuilder é ISupportsStartup suportaStartup)
{ return supportsStartup.UseStartup(startupType);
} O login do hiperlink está visível.
GenericWebHostBuilder Método Privado GenericWebHostBuilder
Instanciar dinamicamente nosso objeto Startup:
Exemplo?? = AtivadorUtilitários.CreateInstance(novo HostServiceProvider(webHostBuilderContext), startupType); Contexto. Propriedades[_startupKey] = instância; Procure pelo método ConfigureServices
var configureServicesBuilder = StartupLoader.FindConfigureServicesDelegate(startupType, context. AnfitriãoAmbiente.NomeAmbiente); var configureServices = configureServicesBuilder.Build(instance);
ConfigureServicesBuilder estático interno FindConfigureServicesDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Tipo startupType, string 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); Procure pelo método ConfigureContainer
var configureContainerBuilder = StartupLoader.FindConfigureContainerDelegate(startupType, context. AnfitriãoAmbiente.NomeAmbiente);
ConfigureContainerBuilder estático interno FindConfigureContainerDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Tipo startupType, string NomeAmbiente) { var configureMethod = FindMethod(startupType, "Configure{0}Container", environmentName, typeof(void), required: false); return new ConfigureContainerBuilder(configureMethod); } Procure pelo método Configure
configureBuilder = StartupLoader.FindConfigureDelegate(startupType, context. AnfitriãoAmbiente.NomeAmbiente);
ConfigureBuilder estático interno FindConfigureDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Tipo startupType, string environmentName)
{ var configureMethod = FindMethod(startupType, "Configure{0}", environmentName, typeof(void), required: true)!; return new ConfigureBuilder(configureMethod);
} Chamado pelo método Build do ConfigureBuilder, o código-fonte é o seguinte:
classe privada ConfigureBuilder { ConfigureBuilder público (MethodInfo configure) { MethodInfo = configure; }
MethodInfo público MethodInfo { get; }
Build de ação pública<IApplicationBuilder> (instância de objeto) { return (applicationBuilder) => Invoke(instance, applicationBuilder); }
private void Invoke(instance de objeto, construtor IApplicationBuilder) { var serviceProvider = builder. Serviços de Aplicação; var parameterInfos = MethodInfo.GetParameters(); var parameters = new object[parameterInfos.Length]; para (var índice = 0; índice < parâmetro Infos.Length; index++) { var parameterInfo = parameterInfos[index]; if (parameterInfo.ParameterType == typeof(IApplicationBuilder)) { parâmetros[índice] = construtor; } senão { tente { parameters[index] = ServiceProvider.GetRequiredService(parameterInfo.ParameterType); } captura (exceção ex) { lançar um novo InvalidOperationException( Resources.FormatMiddlewareFilter_ServiceResolutionFail( parameterInfo.ParameterType.NomeCompleto, parameterInfo.Name, MethodInfo.Name, MethodInfo.DeclaringType.FullName), ex); } } } MethodInfo.Invoke(instância, parâmetros); } } Método de execução
Endereço do método de extensão HostingAbstractionsHostExtensions:
O login do hiperlink está visível.
Eventualmente liga:
/// <summary> Executa uma aplicação e retorna uma Tarefa que só é concluída quando o token é acionado ou quando o desligamento é acionado. /// </summary> <param name="host">O <veja cref="IHost"/> para executar.</param> <param name="token">O token para acionar o desligamento.</param> <returns>O <veja cref="Task"/> que representa a operação assíncrona.</returns> Tarefa pública estática assíncrona RunAsync (este host IHost, token CancellationToken = padrão) { tente { Aguarde o anfitrião. StartAsync(token). ConfigureAwait (false);
Aguarde o anfitrião. WaitForShutdownAsync(token). ConfigureAwait (false); } finalmente { if (host é IAsyncDisposable asyncDisposable) { await asyncDisposable.DisposeAsync(). ConfigureAwait (false); } senão { apresentador. Descartar(); }
} } Anteriormente, quando eu estava construindo um serviço, eu me registrava no serviço IHost, e o código é o seguinte:
serviços. <IHost>AddSingleton(_ => { retorne novo Internal.Host(_appServices, _appServices.GetRequiredService<IHostApplicationLifetime>(), _appServices.GetRequiredService<ILogger<Internal.Host>>(), _appServices.GetRequiredService<IHostLifetime>(), _appServices.GetRequiredService<IOptions<HostOptions>>()); }); Método StartAsync
Endereço:O login do hiperlink está visível.
Task StartAsync async publico(CancellationToken cancellationToken = default) { _logger. Inicial();
usando var combinedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _applicationLifetime.ApplicationStopping); CancellationToken combinadoCancellationToken = combinadoCancellationTokenSource.Token;
await _hostLifetime.WaitForStartAsync(combinedCancellationToken). ConfigureAwait (false);
combinedCancellationToken.ThrowIfCancellationRequested(); _hostedServices = Services.GetService<IEnumerable<IHostedService>>();
foreach (IHostedService hostedService em _hostedServices) { // Fire IHostedService.Start await hostedService.StartAsync(combinedCancellationToken). ConfigureAwait (false);
if (hostedService é BackgroundService backgroundService) { _ = HandleBackgroundException(backgroundService); } }
Fogo IHostAplicaçãoVidaVida. Iniciado _applicationLifetime.NotifyStarted();
_logger. Iniciado(); } (Fim)
|