深入解析 Microsoft.Extensions.Hosting.Abstractions:.NET 通用托管抽象与托管服务原语
语言运行时标准库JIT编译编译器【免费下载链接】runtime.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.项目地址https://gitcode.com/GitHub_Trending/runtime6/runtime点击查看免费下载导读Microsoft.Extensions.Hosting.Abstractions是 .NET 运行时仓库中托管体系Hosting的抽象层核心它定义了如何在一个应用中托管用户代码的统一模式通过宿主Host把配置Configuration、日志Logging、依赖注入DI串联起来并以**托管服务Hosted Service**为原语让 ASP.NET Core 等应用模型与宿主对接。本文以 src/libraries/Microsoft.Extensions.Hosting.Abstractions/README.md 为骨架结合该目录下的全部接口、基类与单元测试源码系统讲解IHost/IHostBuilder抽象、IHostedService/BackgroundService托管服务模型、生命周期与运行辅助方法并给出可复制的实战代码与源码级佐证。一、什么是 Hosting Abstractions托管抽象的价值该包的核心定位在文档中一句话即可概括包含一个核心托管抽象提供使用扩展库在应用中托管用户代码的模式。它本身不提供具体实现实现位于Microsoft.Extensions.Hosting包而是定义了一套稳定的接口契约让上层应用模型可以基于同一套抽象工作。从文档与源码PACKAGE.md看这套抽象封装了一个应用所需的资源与生命周期能力依赖注入DI宿主持有IServiceProvider托管服务与业务服务统一注册、统一解析日志Logging宿主整合日志提供程序配置Configuration宿主构建分层的配置体系启动、停止与通知Starting, stopping and obtaining notifications通过生命周期令牌向应用广播启动/停止事件。它最重要的作用是接线wire upASP.NET Core 这类构建在托管之上的应用模型正是通过托管服务原语与宿主集成的。同时通用托管Generic Host也为三类场景提供了良好的集成支持长运行控制台应用long-running console applications、Windows 服务、ASP.NET Core。二、核心抽象一IHost 与 IHostBuilder1. IHost —— 程序Program抽象IHost.cs 定义了一个正在运行的程序public interface IHost : IDisposable { IServiceProvider Services { get; } Task StartAsync(CancellationToken cancellationToken default); Task StopAsync(CancellationToken cancellationToken default); }Services暴露为程序配置好的服务容器可通过它解析任意已注册服务StartAsync启动程序中配置的所有IHostedService对象应用将持续运行直到被中断或调用IHostApplicationLifetime.StopApplication()StopAsync尝试优雅停止程序传入的CancellationToken表示停止过程不再需要优雅。2. IHostBuilder —— 程序初始化抽象IHostBuilder.cs 定义了宿主的构建阶段契约所有方法均可链式调用且多次调用结果可叠加additive成员作用Properties构建过程中各组件共享状态的中心位置IDictionaryobject, objectConfigureHostConfiguration(ActionIConfigurationBuilder)配置构建器自身的配置源用于初始化后续构建使用的IHostEnvironmentConfigureAppConfiguration(ActionHostBuilderContext, IConfigurationBuilder)配置应用本身的配置结果在HostBuilderContext.Configuration与IHost.Services中均可获取ConfigureServices(ActionHostBuilderContext, IServiceCollection)向容器注册服务可多次调用、结果叠加UseServiceProviderFactoryTContainerBuilder(...)替换创建服务提供程序的工厂支持传入实例或FuncHostBuilderContext, ...上下文工厂ConfigureContainerTContainerBuilder(...)配置实例化后的第三方 DI 容器如 Autofac结果叠加Build()执行初始化动作仅能调用一次返回初始化完成的IHost值得注意的源码细节IHostBuilder上UseServiceProviderFactoryTContainerBuilder(FuncHostBuilderContext, IServiceProviderFactoryTContainerBuilder factory)重载在#if NET分支下提供了默认接口方法DIM实现——默认抛出NotSupportedException。这是为了兼容旧版如 2.2.0.0只实现了非 Func 重载的IHostBuilder实现使其在现代 .NET 上加载时不抛TypeLoadException。这一兼容性设计被 HostBuilderContextTests.cs 中的IHostBuilderDefaultInterfaceMethodTests显式验证。3. HostBuilderContext —— 构建上下文HostBuilderContext.cs 是构建过程中传递给各委托的上下文对象public class HostBuilderContext { public IHostEnvironment HostingEnvironment { get; set; } public IConfiguration Configuration { get; set; } public IDictionaryobject, object Properties { get; } }其构造函数强制要求传入非空的properties字典ArgumentNullException.ThrowIfNull该字典与外部传入的字典共享引用即构建过程中在Properties里写入的键值会实时反映到外部。对应行为均有 HostBuilderContextTests.cs 的测试覆盖如Properties_SharedWithConstructorDictionary验证共享语义。三、核心原语IHostedService 与 BackgroundService1. IHostedService —— 托管服务契约文档明确指出托管服务hosted service是宿主提供的基本原语也是 ASP.NET Core 等应用模型与宿主集成的入口。其定义极其精简IHostedService.cspublic interface IHostedService { Task StartAsync(CancellationToken cancellationToken); Task StopAsync(CancellationToken cancellationToken); }StartAsync当应用宿主准备好启动服务时触发传入的CancellationToken表示启动过程已被中止StopAsync当应用宿主执行优雅关闭时触发传入的CancellationToken表示关闭过程不再要求优雅。2. BackgroundService —— 长运行任务的现成基类开发者通常不需要自己实现IHostedService的完整生命周期继承 BackgroundService.cs 即可public abstract class BackgroundService : IHostedService, IDisposable { public virtual Task? ExecuteTask _executeTask; protected abstract Task ExecuteAsync(CancellationToken stoppingToken); public virtual Task StartAsync(CancellationToken cancellationToken); public virtual Task StopAsync(CancellationToken cancellationToken); public virtual void Dispose(); }其内部工作机制值得深入理解源码级启动StartAsync内部通过CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)创建链接令牌将启动令牌与停止令牌关联随后在后台执行ExecuteAsync(stoppingToken)并保存返回的Task到ExecuteTask。StartAsync本身总是返回已完成的任务ExecuteAsync的任何结果统一由 Host 处理。停止StopAsync先取消_stoppingCts向执行中的ExecuteAsync发送停止信号再等待任务结束在#if NET分支使用_executeTask.WaitAsync(cancellationToken)实现等待执行任务完成或停止令牌触发并刻意SuppressThrowing忽略OperationCanceledException因为取消执行任务必然抛出该异常属预期行为非 NET 目标框架如 .NET Framework则退化为Task.WhenAny的等值实现。执行中的取消令牌传入ExecuteAsync的stoppingToken正是文档所述的当StopAsync被调用时触发的令牌这是后台任务响应优雅关闭的标准通道。一个标准的定时型后台服务示例ExecuteAsync返回代表长运行操作生命周期的任务stoppingToken用于响应关闭public sealed class TimedHostedService : BackgroundService { private readonly ILoggerTimedHostedService _logger; public TimedHostedService(ILoggerTimedHostedService logger) _logger logger; protected override async Task ExecuteAsync(CancellationToken stoppingToken) { _logger.LogInformation(Timed Hosted Service running.); using PeriodicTimer timer new(TimeSpan.FromSeconds(5)); try { while (await timer.WaitForNextTickAsync(stoppingToken)) { _logger.LogInformation(Timed Hosted Service is doing background work.); } } catch (OperationCanceledException) { _logger.LogInformation(Timed Hosted Service is stopping.); } } }四、生命周期管理应用级、宿主级与服务级三层协同1. IHostApplicationLifetime —— 应用级生命周期令牌IHostApplicationLifetime.cs 让消费方订阅应用生命周期事件该接口被设计为不可由用户替换宿主内部统一实现成员触发时机CancellationToken ApplicationStarted宿主已完全启动、即将等待优雅关闭时触发CancellationToken ApplicationStopping宿主开始优雅关闭时触发可能仍有请求在途关闭会阻塞直到所有回调完成CancellationToken ApplicationStopped宿主完成优雅关闭后触发所有请求应已结束应用不会退出直到所有回调完成void StopApplication()主动请求终止当前应用示例在ApplicationStopping上注册清理回调确保关闭前完成资源释放public class GracefulShutdownHandler : IHostedService { private readonly IHostApplicationLifetime _lifetime; public GracefulShutdownHandler(IHostApplicationLifetime lifetime) _lifetime lifetime; public Task StartAsync(CancellationToken cancellationToken) { _lifetime.ApplicationStopping.Register(() { // 执行清理刷新缓冲、释放连接、通知对端下线等 }); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) Task.CompletedTask; }2. IHostLifetime —— 宿主级启动/停止协调IHostLifetime.cs 负责跟踪宿主本身的生命周期WaitForStartAsync(CancellationToken)在IHost.StartAsync开头调用会阻塞后续启动流程直到其完成可用来延迟启动直到外部事件就绪例如控制台宿主等待 CtrlC、服务宿主等待系统服务管理器信号StopAsync(CancellationToken)由IHost.StopAsync调用指示宿主正在停止、到了关闭时刻。3. IHostedLifecycleService —— 托管服务的精细生命周期钩子当应用需要在StartAsync/StopAsync前后插入逻辑时可实现 IHostedLifecycleService.cs它继承IHostedServicepublic interface IHostedLifecycleService : IHostedService { Task StartingAsync(CancellationToken cancellationToken); // StartAsync 之前 Task StartedAsync(CancellationToken cancellationToken); // StartAsync 之后 Task StoppingAsync(CancellationToken cancellationToken); // StopAsync 之前 Task StoppedAsync(CancellationToken cancellationToken); // StopAsync 之后 }由此形成的完整启动序列为StartingAsync→StartAsync→StartedAsync关闭序列为StoppingAsync→StopAsync→StoppedAsync。五、环境抽象IHostEnvironment 与标准环境名1. IHostEnvironment —— 托管环境信息IHostEnvironment.cs 提供应用运行环境信息宿主会自动从配置填充这些属性属性含义与自动填充规则EnvironmentName环境名称宿主自动设置为配置中environment键的值ApplicationName应用名称宿主自动设置为包含应用入口点的程序集名ContentRootPath包含应用内容文件的目录的绝对路径ContentRootFileProvider指向ContentRootPath的IFileProvider对应的配置键常量定义在 HostDefaults.csapplicationName、environment、contentRoot。这些键既可用作宿主配置Host configuration的键名也可通过环境变量如DOTNET_ENVIRONMENT、ASPNETCORE_ENVIRONMENT注入。2. Environments —— 标准环境名常量Environments.cs 定义了三个常用环境名Development开发环境可启用生产环境不应暴露的特性出于性能成本考虑作用域验证与依赖验证只在开发环境执行Staging预发布环境用于上线前验证应用变更Production生产环境应配置为最大化安全、性能与健壮性。3. 环境判断扩展方法HostEnvironmentEnvExtensions.cs 为IHostEnvironment提供了便捷判断方法public static bool IsDevelopment(this IHostEnvironment hostEnvironment); public static bool IsStaging(this IHostEnvironment hostEnvironment); public static bool IsProduction(this IHostEnvironment hostEnvironment); public static bool IsEnvironment(this IHostEnvironment hostEnvironment, string environmentName);核心实现IsEnvironment使用StringComparison.OrdinalIgnoreCase做大小写不敏感比较因此development、Development等价。对应测试见 HostEnvironmentEnvExtensionsTests.cs 与 EnvironmentsTests.cs后者验证三个常量值分别为Development、Staging、Production。典型用法public void Configure(IHostEnvironment env, ILoggerFactory loggerFactory) { if (env.IsDevelopment()) { // 开发环境专属详细日志、开发异常页等 } }兼容性说明旧接口IHostingEnvironmentIHostingEnvironment.cs已被标记[Obsolete]官方推荐统一使用IHostEnvironment对应旧扩展类HostingEnvironmentExtensions也随其一起标记为 obsolete。应用代码新开发应直接面向IHostEnvironment。六、注册托管服务AddHostedService 扩展方法托管服务通过 ServiceCollectionHostedServiceExtensions.cs 注册到IServiceCollection// 泛型重载按类型注册 public static IServiceCollection AddHostedServiceTHostedService(this IServiceCollection services) where THostedService : class, IHostedService; // 工厂重载按委托创建实例 public static IServiceCollection AddHostedServiceTHostedService(this IServiceCollection services, FuncIServiceProvider, THostedService implementationFactory) where THostedService : class, IHostedService;源码实现要点两者都通过TryAddEnumerable(ServiceDescriptor.SingletonIHostedService, THostedService())注册即注册的抽象是IHostedService本身而不是具体类型THostedService使用TryAddEnumerable保证同一实现类型不会重复注册生命周期为单例Singleton。文档特别提醒若要同时注册具体类型本身必须单独注册。官方给出的推荐写法services.AddSingletonSomeService(); services.AddHostedService(sp sp.GetRequiredServiceSomeService());这样SomeService及其依赖由 DI 容器统一管理托管服务通过工厂解析同一单例实例。七、运行与停止宿主HostingAbstractionsHostExtensionsHostingAbstractionsHostExtensions.cs 为IHost提供同步/异步运行辅助方法是控制台应用、Windows 服务与 ASP.NET Core 启动代码的公共基础方法行为Start(this IHost host)同步启动宿主StopAsync(this IHost host, TimeSpan timeout)在指定超时内优雅停止超时后服务器可终止剩余活动连接WaitForShutdown(this IHost host)阻塞调用线程直到通过 CtrlC 或 SIGTERM 触发关闭Run(this IHost host)运行应用并阻塞直到关闭触发且所有IHostedService停止RunAsync(this IHost host, CancellationToken token)异步版本token 触发或关闭触发时完成运行结束后自动释放宿主WaitForShutdownAsync(this IHost host, CancellationToken token)返回在关闭触发时完成的Task实现细节WaitForShutdownAsync从host.Services解析IHostApplicationLifetime将外部 token 注册为调用StopApplication()然后等待ApplicationStopping令牌在#if NET分支通过Task.Delay(Timeout.Infinite, ...)配合SuppressThrowing实现阻塞。RunAsync在finally中优先走IAsyncDisposable.DisposeAsync()否则回退到同步Dispose()。对应地HostingAbstractionsHostBuilderExtensions.cs 为IHostBuilder提供Start()/StartAsync()快捷方法内部先Build()再StartAsync()。典型控制台应用入口结合泛型主机实现using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; HostApplicationBuilder builder Host.CreateApplicationBuilder(args); builder.Services.AddHostedServiceTimedHostedService(); using IHost host builder.Build(); await host.RunAsync();其中RunAsync负责启动托管服务 → 等待ApplicationStoppingCtrlC/SIGTERM→ 优雅停止所有托管服务 → 释放宿主。八、新一代宿主构建抽象IHostApplicationBuilder面向 .NET 7 的HostApplicationBuilder模式基于 IHostApplicationBuilder.cs 抽象其成员比IHostBuilder更贴近构建一个应用的直觉成员作用Properties构建期间组件共享状态的中心位置ConfigurationIConfigurationManager可变配置集合可继续追加配置源追加后其当前视图立即更新Environment宿主环境信息LoggingILoggingBuilder日志提供程序组合点MetricsIMetricsBuilder启用指标并指定输出方向的构建器Services应用服务集合用户服务与框架服务ConfigureContainerTContainerBuilder(factory, configure)注册第三方容器工厂IServiceProvider在构建时创建因此configure委托会在所有服务注册完成后运行多次调用会替换先前存储的工厂与委托九、异常与资源类型1. HostAbortedExceptionHostAbortedException.cs 是当IHost被停止以表示宿主正在优雅停止时抛出的密封异常。文档明确该异常不应由用户代码抛出或捕获。它提供默认消息来自Strings.resx的SR.HostAbortedExceptionMessage、自定义消息与内部异常三个构造函数重载。2. 生命周期接口的演进目录中还保留了IApplicationLifetime.cs与EnvironmentName.cs等历史类型分别与IHostingEnvironment配套使用随旧抽象一并废弃当前路线统一收敛到IHostApplicationLifetimeIHostEnvironmentEnvironments的新三元组。十、源码布局、测试与质量门槛1. 源码与测试组织接口/基类/扩展方法src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/23 个源文件 Strings.resx资源 PACKAGE.md包说明单元测试src/libraries/Microsoft.Extensions.Hosting.Abstractions/tests/含 EnvironmentsTests.cs、HostBuilderContextTests.cs、HostDefaultsTests.cs、HostEnvironmentEnvExtensionsTests.cs参考程序集/API 面src/libraries/Microsoft.Extensions.Hosting.Abstractions/ref/Microsoft.Extensions.Hosting.Abstractions.cs解决方案src/libraries/Microsoft.Extensions.Hosting.Abstractions/Microsoft.Extensions.Hosting.Abstractions.slnx2. 贡献门槛Contribution Bar原文档明确该库接受新特性、新 API、bug 修复与性能改进详见 src/libraries/README.md 的主贡献门槛说明。同时文档也坦诚这些 API 与功能已成熟目前没有积极的投资计划但对更深入的投资想法持开放态度未来理想的投资方向包括支持全部 .NET Core 应用模型WinForms、WPF、UWP、Xamarin、短运行批量控制台任务、Blazor客户端为托管服务提供idle/pause空闲/暂停支持提供更多托管服务基类例如timer-based基于定时器与trigger-based基于触发器的基类。3. 部署方式Microsoft.Extensions.Hosting.Abstractions有两个交付通道文档明确说明已包含在ASP.NET Core 共享框架shared framework中使用 ASP.NET Core 的应用开箱即得同时作为out-of-bandOOB包独立发布可被任意项目直接引用——这正是它同时服务于长运行控制台应用、Windows 服务与 ASP.NET Core 三类场景的包分发基础。十一、从抽象到实现理解抽象层在 .NET 托管体系中的位置综合本文分析可以梳理出该抽象包在托管体系中的分层职责┌─────────────────────────────────────────────────────────┐ │ 应用模型ASP.NET Core / Worker / Windows 服务… │ │ └─ 通过 IHostedService / IHostedLifecycleService │ ├─────────────────────────────────────────────────────────┤ │ Microsoft.Extensions.Hosting.Abstractions本文主题 │ │ IHost · IHostBuilder · IHostEnvironment │ │ IHostedService · BackgroundService │ │ IHostApplicationLifetime · IHostLifetime │ │ AddHostedService / Run / RunAsync 等扩展 │ ├─────────────────────────────────────────────────────────┤ │ Microsoft.Extensions.Hosting实现包位于本仓库 │ │ src/libraries/Microsoft.Extensions.Hosting/ │ │ HostBuilder / Host / ConsoleLifetime 等具体实现 │ └─────────────────────────────────────────────────────────┘抽象层只定义契约实现层提供HostBuilder、Host等具体类型应用模型如 ASP.NET Core 的WebApplication再基于这两层组装。这种抽象与实现分离的设计让上层应用模型可以稳定依赖接口、让第三方容器Autofac 等可以通过IServiceProviderFactory无侵入接入、也让测试可以用最小桩实现如HostBuilderContextTests中的MinimalHostBuilder验证契约行为。结语Microsoft.Extensions.Hosting.Abstractions虽是一个纯抽象包却是整个 .NET 托管体系的契约基石。理解IHost/IHostBuilder的构建与运行两阶段、掌握IHostedService/BackgroundService的启动停止语义、善用IHostApplicationLifetime与IHostedLifecycleService的生命周期钩子是编写健壮的后台任务、Windows 服务与跨模型复用代码的必备技能。深入阅读本仓库 Microsoft.Extensions.Hosting.Abstractions 源码目录 及其测试可以让你对宿主如何管理你的代码有完整的源码级认知。赞分享语言运行时标准库JIT编译编译器【免费下载链接】runtime.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.项目地址https://gitcode.com/GitHub_Trending/runtime6/runtime点击查看免费下载相关推荐linkding 托管部署指南托管服务、托管平台与自托管方案全解析linkding 托管部署指南托管服务、托管平台与自托管方案全解析 linkding 是一个定位为极简、快速、易于用 Docker 部署的自托管书签管理器后端前端Expert云服务托管服务与SaaS方案深度解析Expert云服务托管服务与SaaS方案深度解析 引言为什么需要Elixir语言服务器的云服务 在当今云原生时代开发工具正在从本地安装向云端服务迁移。E开发工具IDE构建高性能语言应用47万英语词汇数据库的完整技术方案构建高性能语言应用47万英语词汇数据库的完整技术方案 在自然语言处理和语言应用开发领域高质量词汇数据库是技术架构的核心基础。english words项目提数据集创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →