Blazor中服务及普通类含非注入参数的构造函数注入实现咨询
直接解决方案
你在Startup.ConfigureServices中注册时,使用DI容器提供的工厂注册重载即可,不需要提前获取IServiceProvider:
// yourCustomStuff 是你提前准备好的自定义参数 services.AddSingleton<MyService>(serviceProvider => new MyService(yourCustomStuff, serviceProvider));
这个重载的入参是容器构建完成后自动传入的IServiceProvider实例,完美匹配你的构造函数参数要求。
通用问题解答
1. 构造函数同时包含注入服务和非注入参数的场景,能否实现依赖注入?如何实现?
可以实现,根据非注入参数的生成时机选对应方案即可:
- 若非注入参数在服务注册阶段就可以确定:直接用上述工厂注册重载,所有注入服务都可以从工厂方法入参的
IServiceProvider中获取,和自定义参数一起传入构造函数即可。 - 若非注入参数是运行时动态生成(比如用户请求参数、业务运行中生成的变量):使用抽象工厂模式封装构造逻辑:
首先定义工厂类:
注册工厂:public class MyServiceFactory { private readonly IServiceProvider _serviceProvider; // 工厂自身的依赖由DI容器自动注入 public MyServiceFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } // 调用方仅需传入自定义参数 public MyService Create(object customParameter) { return new MyService(customParameter, _serviceProvider); } }
使用时注入services.AddSingleton<MyServiceFactory>();MyServiceFactory,调用Create方法传入动态自定义参数即可得到MyService实例,无需关心注入参数的获取逻辑。
2. 无法直接访问待注入的服务实例,能否通过构造函数实现依赖注入?如何实现?
可以实现,就是上述的抽象工厂方案:你不需要直接访问任何待注入的服务实例,只需要将工厂注入到使用位置,工厂会自动持有DI容器的服务提供器,帮你完成所有注入参数的赋值,调用方仅需传递非注入的自定义参数即可。
注意事项
如果你的MyService是单例服务,不要直接用注入的IServiceProvider解析范围服务(Scoped),会导致生命周期不匹配引发内存泄漏或逻辑错误。需要解析范围服务时请手动创建范围:
using var scope = _sProvider.CreateScope(); var requiredScopedService = scope.ServiceProvider.GetRequiredService<MyScopedService>();
内容的提问来源于stack exchange,提问作者neggenbe
相关产品推荐
相关产品推荐

