Огляд:
Почніть з приєднання відкритої адреси GitHub ASP.NET Core
Вхід за гіперпосиланням видно.
Вхід за гіперпосиланням видно.
Після створення нового проєкту ASP.NET Core 3.1 програмний код виглядає так:
Ми глибоко розглянули код введення, поєднаний із вихідним кодом GitHub.
Код хоста:Вхід за гіперпосиланням видно.
Метод CreateDefaultBuilder
Тут ми створюємо об'єкт HostBuilder, який успадковує від IHostBuilder, і додаємо системно визначені делегати, такі як :appsettings.json, appsettings. {env. EnvironmentName}.json конфігураційний файл, який згодом поверне: інтерфейс IHostBuilder.
Код HostBuilder:Вхід за гіперпосиланням видно.
Метод Build зрештою буде викликаний.
Публічний IHost Build()
{ якщо (_hostBuilt) { throw new InvalidOperationException(SR. BuildCalled); } _hostBuilt = істинно;
BuildHostConfiguration(); СтворитиХостингСередовище(); CreateHostBuilderContext(); BuildAppConfiguration(); CreateServiceProvider();
повернутися _appServices.GetRequiredService<IHost>();
} Метод BuildHostConfiguration
приватний IConfiguration _hostConfiguration; IConfigurationBuilder configBuilder = новий ConfigurationBuilder() Викликайте делегата для додавання конфігурації по черзі
Метод CreateHostingEnvironment
приватне середовище хостингу _hostingEnvironment; _hostingEnvironment = новий HostingEnvironment()
{ ApplicationName = _hostConfiguration[HostDefaults.ApplicationKey], EnvironmentName = _hostConfiguration[HostDefaults.EnvironmentKey] ?? Середовища. Виробництво, ContentRootPath = ResolveContentRootPath(_hostConfiguration[HostDefaults.ContentRootKey], AppContext.BaseDirectory), }; Метод CreateHostBuilderContext
приватний HostBuilderContext _hostBuilderContext; _hostBuilderContext = новий HostBuilderContext(Властивості)
{ HostingEnvironment = _hostingEnvironment, Конфігурація = _hostConfiguration }; Метод BuildAppConfiguration
Інтегруйте інформацію про конфігурацію знову
IConfigurationBuilder configBuilder = новий ConfigurationBuilder() . SetBasePath(_hostingEnvironment.ContentRootPath) . AddConfiguration(_hostConfiguration, shouldDisposeConfiguration: true); _appConfiguration = configBuilder.Build(); _hostBuilderContext.Конфігурація = _appConfiguration; CreateServiceProvider method
var services = новий ServiceCollection(); Зареєструйте сервіс, викликайте делегата та додайте сервіс, визначений користувачем.
Метод розширення GenericHostBuilderExtensions
Вхід за гіперпосиланням видно.
ConfigureWebHost extension method
Щоб зареєструвати GenericWebHostService як бекенд-сервіс:
Будівельник. ConfigureServices((context, services) => services. <GenericWebHostService>AddHostedService()); Код GenericWebHostService:Вхід за гіперпосиланням видно.
public async Task StartAsync(CancellationToken cancellationToken) { HostingEventSource.Log.HostStart();
var serverAddressesFeature = Server.Features.Get<IServerAddressesFeature>(); var addresses = serverAddressesFeature?. Адреси; якщо (адреси != null && !адреси. IsReadOnly та адреси. Кількість == 0) { var urls = Configuration[WebHostDefaults.ServerUrlsKey]; if (!string. IsNullOrEmpty(urls)) { serverAddressesFeature!. PreferHostingUrls = WebHostUtilities.ParseBool(Configuration, WebHostDefaults.PreferHostingUrlsKey);
foreach (значення var у URL. Спліт('; ', StringSplitOptions.RemoveEmptyEntries)) { адреси. Add(value); } } }
RequestDelegate? застосування = null;
спробуйте { var configure = Options.ConfigureApplication;
if (configure == null) { throw new InvalidOperationException($"No application configurened. Будь ласка, вкажіть заявку через IWebHostBuilder.UseStartup, IWebHostBuilder.Configure, або вказавши асемблею запуску через {nameof(WebHostDefaults.StartupAssemblyKey)} у конфігурація веб-хостів.»); }
var builder = ApplicationBuilderFactory.CreateBuilder(Server.Features);
foreach (фільтр var у StartupFilters.Reverse()) { configure = filter. Configure(configure); }
configure(builder);
Побудуйте конвеєр запитів application = конструктор. Build(); } catch (виняток, наприклад) { Logger.ApplicationError(ex);
якщо (! Options.WebHostOptions.CaptureStartupErrors) { кидати; }
var showDetailedErrors = HostingEnvironment.IsDevelopment() || Options.WebHostOptions.DetailedErrors;
application = ErrorPageBuilder.BuildErrorPageApplication(HostingEnvironment.ContentRootFileProvider, Logger, showDetailedErrors, ex); }
var httpApplication = новий HostingApplication (application, Logger, DiagnosticListener, HttpContextFactory);
await Server.StartAsync(httpApplication, cancellationToken);
якщо (адреси != null) { foreach (VAR адреса в адресах) { LifetimeLogger.ListeningOnAddress(адреса); } }
if (Logger.IsEnabled(LogLevel.Debug)) { foreach (var assembly in Options.WebHostOptions.GetFinalHostingStartupAssemblies()) { Logger.StartupAssemblyLoaded(асемблер); } }
if (Options.HostingStartupExceptions != null) { foreach (var exception in Options.HostingStartupExceptions.InnerExceptions) { Logger.HostingStartupAssemblyError(виключення); } } }
var webhostBuilder = новий GenericWebHostBuilder(builder, webHostBuilderOptions); Вхід за гіперпосиланням видно.
Метод розширення WebHostBuilderExtensions
Надає об'єкт startupType для викликів IWebHostBuilder.
цей IWebHostBuilder hostBuilder if (hostBuilder — ISupportsStartup підтримує Startup)
{ return supportsStartup.UseStartup(startupType);
} Вхід за гіперпосиланням видно.
GenericWebHostBuilder Приватний метод GenericWebHostBuilder
Динамічно інстанціюйте наш об'єкт Start:
Інстанс ?? = 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)] Type 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); повернути новий ConfigureServicesBuilder(servicesMethod); Пошукайте метод ConfigureContainer
var configureContainerBuilder = StartupLoader.FindConfigureContainerDelegate(startupType, context. HostingEnvironment.EnvironmentName);
внутрішній статичний ConfigureContainerBuilder FindConfigureContainerDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Тип startupType, рядок environmentName) { var configureMethod = FindMethod(startupType, "Configure{0}Container", environmentName, typeof(void), required: false); повернути новий ConfigureContainerBuilder(configureMethod); } Пошукайте метод Configure
configureBuilder = StartupLoader.FindConfigureDelegate(startupType, context. HostingEnvironment.EnvironmentName);
внутрішній статичний ConfigureBuilder FindConfigureDelegate([DynamicallyAccessedMembers(StartupLinkerOptions.Accessibility)] Type startupType, string environmentName)
{ var configureMethod = FindMethod(startupType, "Configure{0}", environmentName, typeof(void), required: true)!; повернути новий ConfigureBuilder(configureMethod);
} Викликаний методом ConfigureBuilder Build, вихідний код виглядає так:
приватний клас ConfigureBuilder { public ConfigureBuilder(MethodInfo configure) { MethodInfo = конфігурувати; }
public MethodInfo MethodInfo { get; }
публічний<IApplicationBuilder> Action Build (екземпляр об'єкта) { return (applicationBuilder) => Invoke (екземпляр, applicationBuilder); }
private void Invoke(object instance, IApplicationBuilder builder) { var serviceProvider = builder. ApplicationServices; var parameterInfos = MethodInfo.GetParameters(); var parameters = новий об'єкт[parameterInfos.Length]; для (індекс VAR = 0; index < parameterInfos.Length; index++) { var parameterInfo = parameterInfos[index]; якщо (parameterInfo.ParameterType == typeof(IApplicationBuilder)) { параметри[індекс] = будівельник; } інше { спробуйте { parameters[index] = serviceProvider.GetRequiredService(parameterInfo.ParameterType); } catch (виняток, наприклад) { throw new InvalidOperationException( Resources.FormatMiddlewareFilter_ServiceResolutionFail( parameterInfo.ParameterType.FullName, parameterInfo.Name, MethodInfo.Name, MethodInfo.DeclaringType.FullName), ex); } } } MethodInfo.Invoke (екземпляр, параметри); } } Метод запуску
Адреса методу розширення HostingAbstractionsHostExtensions:
Вхід за гіперпосиланням видно.
Зрештою дзвонить:
/// <summary> Запускає додаток і повертає завдання, яке виконується лише тоді, коли токен спрацьовує або вимикається. /// </summary> <param name="host">The <see cref="IHost"/> для запуску</param>. <param name="token">Токен, що запускає вимкнення.</param> <returns><див. cref="Завдання"/>, що представляє асинхронну операцію.</returns> публічний статичний асинхронний Task RunAsync (цей IHost хост, токен CancellationToken = за замовчуванням) { спробуйте { Чекайте ведучого. StartAsync(токен). ConfigureAwait(хибно);
Чекайте ведучого. WaitForShutdownAsync(token). ConfigureAwait(хибно); } нарешті { якщо (хост є IAsyncDisposable asyncDisposable) { waitit asyncDisposable.DisposeAsync(). ConfigureAwait(хибно); } інше { Господар. Позбавлятися(); }
} } Раніше, коли я створював сервіс, я реєструвався на сервіс IHost, і код був таким:
Послуги. <IHost>AddSingleton(_ => { повернути новий Internal.Host(_appServices, _appServices.GetRequiredService<IHostApplicationLifetime>(), _appServices.GetRequiredService<ILogger<Internal.Host>>(), _appServices.GetRequiredService<IHostLifetime>(), _appServices.GetRequiredService<<HostOptions>IOptions>()); }); Метод StartAsync
Адреса:Вхід за гіперпосиланням видно.
public async Task StartAsync(CancellationToken cancellationToken = за замовчуванням) { _logger. Starting();
використання var combinedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _applicationLifetime.ApplicationStopping); CancellationToken combinedCancellationToken = combinedCancellationTokenSource.Token;
Чекайте _hostLifetime.WaitForStartAsync(combinedCancellationToken). ConfigureAwait(хибно);
combinedCancellationToken.ThrowIfCancellationRequested(); _hostedServices = Services.GetService<IEnumerable<IHostedService>>();
foreach (IHostedService hostedService у _hostedServices) { // Fire IHostedService.Start waitit hostedService.StartAsync(combinedCancellationToken). ConfigureAwait(хибно);
якщо (hostedService — це BackgroundService backgroundService) { _ = HandleBackgroundException(backgroundService); } }
Fire IHostApplicationLife.Started _applicationLifetime.NotifyStarted();
_logger. Start(); } (Кінець)
|