如何在.NET6控制台应用Program.cs中获取ServiceProvider(保留Startup.cs)
解决.NET6控制台应用中服务实例获取的问题
你现在的问题核心是没有构建完整的服务容器(ServiceProvider),ActivatorUtilities.CreateInstance<T>需要依赖ServiceProvider才能自动解析服务的依赖项,直接调用肯定会报错。完全没必要移除Startup.cs,给你两种可行方案:
方案一:保留Startup.cs,正确构建服务容器
在Program.cs里,你需要先通过Startup配置服务集合,再构建ServiceProvider,之后才能获取服务实例:
class Program{ static void Main(string[] args) { // 1. 构建配置 var builder = new ConfigurationBuilder() .AddJsonFile("appsettings.json", true, true); var config = builder.Build(); // 2. 初始化Serilog(因为Startup里注册了Serilog日志,需要先配置好) Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(config) .CreateLogger(); try { // 3. 创建Startup实例,配置服务集合 var startup = new Startup(config); var services = new ServiceCollection(); startup.ConfigureServices(services); // 4. 构建ServiceProvider var serviceProvider = services.BuildServiceProvider(); // 5. 获取服务实例(两种方式都可以) // 方式一:直接通过ServiceProvider获取 var httpService = serviceProvider.GetRequiredService<IHttpService>(); // 方式二:用ActivatorUtilities(适合需要额外参数的场景) var httpServiceViaActivator = ActivatorUtilities.CreateInstance<HttpService>(serviceProvider); // 后续使用服务... } finally { Log.CloseAndFlush(); } } }
方案二:移除Startup.cs,用.NET6控制台极简写法
如果觉得Startup.cs有点冗余,完全可以直接在Program.cs里注册服务,更贴合.NET6的轻量化风格:
class Program{ static void Main(string[] args) { // 1. 构建配置 var config = new ConfigurationBuilder() .AddJsonFile("appsettings.json", true, true) .Build(); // 2. 初始化Serilog Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(config) .CreateLogger(); try { // 3. 直接注册服务 var services = new ServiceCollection(); services.Configure<Files>(config.GetSection("Files")); services.AddLogging(configure => configure.AddSerilog()); services.AddScoped<IHttpService, HttpService>(); // 4. 构建ServiceProvider并获取服务 var serviceProvider = services.BuildServiceProvider(); var httpService = serviceProvider.GetRequiredService<IHttpService>(); // 后续使用服务... } finally { Log.CloseAndFlush(); } } }
关键说明
- 不管用不用Startup.cs,必须先构建ServiceProvider,所有依赖注入的服务都要通过它来解析。
ActivatorUtilities.CreateInstance通常用于需要给服务传递额外参数的场景,如果只是单纯获取注册好的服务,直接用GetRequiredService<T>更简单直接。
内容的提问来源于stack exchange,提问作者Robert Green MBA
相关产品推荐
相关产品推荐

