调用IServiceScopeFactory的GetRequiredService时能否传入构造参数?
IServiceScopeFactory是否支持创建服务时传入自定义参数
原生IServiceScopeFactory本身不直接支持该操作。它创建的作用域容器仅会基于启动阶段预先注册的服务描述解析实例,直接调用GetRequiredService这类方法没有传自定义参数的入口。
你可以通过以下两种成熟方案实现需求:
方案1:预先注册服务工厂
在Startup的服务注册阶段,提前注册一个接收自定义参数的委托工厂,示例代码如下:
// 注册服务工厂,泛型第一个参数是你要传入的自定义参数类型,第二个是返回的服务接口类型 services.AddTransient<Func<User, IUserCarrierService>>(sp => user => new UserCarrierService(user, sp.GetRequiredService<你的其他依赖类型>()));
之后在HostedService中就可以通过作用域拿到工厂,传入自定义参数生成实例:
using (var scope = ScopeFactory.CreateScope()) { var carrierFactory = scope.ServiceProvider.GetRequiredService<Func<User, IUserCarrierService>>(); // 传入你自定义的user实例生成服务 var userCarrierService = carrierFactory(customUserInstance); }
方案2:使用ActivatorUtilities工具类
.NET DI内置的ActivatorUtilities可以在创建实例时混合传入自定义参数和容器中的依赖,不需要预先注册工厂,使用更灵活:
using (var scope = ScopeFactory.CreateScope()) { // 第一个参数是作用域的ServiceProvider,后面按顺序传入自定义构造参数,剩下的依赖会自动从容器中解析 var userCarrierService = ActivatorUtilities.CreateInstance<UserCarrierService>(scope.ServiceProvider, customUserInstance); }
运行时能否覆盖Startup阶段已构建的DI注册规则
默认的Microsoft官方DI容器不支持该操作。当主机启动完成、IServiceProvider构建之后,整个容器的注册规则是只读的,没有提供修改、覆盖已有注册的公开API。
如果确实有动态调整注册的需求,有两个可选方向:
- 替换为支持动态注册的第三方DI容器,比如Autofac、Castle Windsor,这类容器支持在运行时新增、覆盖已有的服务注册
- 仅针对需要自定义实例的场景使用上述的工厂模式或
ActivatorUtilities方案,不需要修改全局注册规则,即可满足绝大多数自定义实例创建的需求
内容的提问来源于stack exchange,提问作者Michael J. Zak
相关产品推荐
相关产品推荐

