如何在Program.cs中访问Startup.cs定义的单例服务?
解决从Program.cs访问Startup中注册的单例服务时的“未注册服务”异常
这个问题我之前也碰到过,核心原因是你注册服务的方式和获取服务的方式不匹配,让我给你拆解一下解决方案:
问题根源
你在ConfigureServices里注册的是接口到实现类的映射:
services.AddSingleton<IBenutzerLizenzDaten, BenutzerLizenzDaten>();
这意味着DI容器只知道通过IBenutzerLizenzDaten这个接口类型来解析对应的实例,并没有直接注册BenutzerLizenzDaten这个具体类的服务条目。所以当你调用GetRequiredService<BenutzerLizenzDaten>()时,容器找不到对应的注册项,自然就抛出「未注册服务」的异常了。
两种解决方案
方法一:通过接口类型获取服务(推荐)
这是最符合依赖注入设计原则的做法——面向抽象(接口)编程,直接修改Program.cs里的获取代码:
public static void Main(string[] args){ ... var host = CreateHostBuilder(args).Build(); // 改用接口类型获取服务 var benutzerLizenzDaten = host.Services.GetRequiredService<IBenutzerLizenzDaten>(); benutzerLizenzDaten.Init(); host.Run(); }
这种方式不仅能解决问题,还能降低代码耦合度,让后续的测试和维护更方便。
方法二:同时注册具体类(仅特殊场景使用)
如果你因为某些特殊原因必须直接通过BenutzerLizenzDaten类来获取实例,可以在Startup的ConfigureServices里补充注册这个类的单例,确保容器能识别它:
// 方式1:显式注册类的单例,并复用同一个实例给接口 services.AddSingleton<BenutzerLizenzDaten>(); services.AddSingleton<IBenutzerLizenzDaten>(sp => sp.GetRequiredService<BenutzerLizenzDaten>()); // 方式2:先创建实例,再同时绑定接口和类(保证是同一个单例) var lizenzInstance = new BenutzerLizenzDaten(); services.AddSingleton<IBenutzerLizenzDaten>(lizenzInstance); services.AddSingleton<BenutzerLizenzDaten>(lizenzInstance);
修改完成后,你原来在Program.cs里的代码就能正常获取到服务实例了。
内容的提问来源于stack exchange,提问作者WMY
相关产品推荐
相关产品推荐

