如何使用DI实例化带动态参数的服务类并访问DI服务?
场景一:构造函数含依赖服务与动态参数的DI注册方案
你的类构造函数如下:
public MyClass(SomeRequiredService srs, string someRandomInput) { }
要实现每次获取MyClass实例时传入不同的someRandomInput,可以用以下两种方式:
方式一:注册工厂委托
先正常注册依赖的SomeRequiredService,再向DI容器注册一个Func<string, MyClass>委托,用于动态创建实例:// 注册基础依赖服务 services.AddScoped<SomeRequiredService>(); // 注册工厂委托,传入动态参数创建MyClass services.AddScoped<Func<string, MyClass>>(sp => randomInput => new MyClass(sp.GetRequiredService<SomeRequiredService>(), randomInput));使用时,注入或获取这个委托,传入参数即可生成实例:
var myClassFactory = serviceProvider.GetRequiredService<Func<string, MyClass>>(); var instance1 = myClassFactory("随机输入1"); var instance2 = myClassFactory("随机输入2");方式二:手动解析依赖并创建实例
直接从DI容器获取已注册的SomeRequiredService,再手动实例化MyClass:var requiredService = serviceProvider.GetRequiredService<SomeRequiredService>(); var myClassInstance = new MyClass(requiredService, "当前随机输入");
场景二:构造函数仅含动态参数时访问DI服务的方案
你的类构造函数如下:
public MyClass(string someRandomInput) { // 如何在此处通过DI访问已注册的服务? }
推荐以下几种方案,按最佳实践优先级排序:
方案一:修改构造函数,添加依赖服务参数(推荐)
遵循构造函数注入的最佳实践,将需要的服务直接加入构造函数参数:public MyClass(string someRandomInput, SomeRequiredService srs) { // 直接使用srs服务 }后续可结合场景一的工厂委托方式,动态传入
someRandomInput并获取实例。方案二:注入IServiceProvider到构造函数
将IServiceProvider作为构造参数传入,通过它获取所需服务:public MyClass(string someRandomInput, IServiceProvider serviceProvider) { var requiredService = serviceProvider.GetRequiredService<SomeRequiredService>(); // 使用服务 }注册时同样用工厂委托封装:
services.AddScoped<Func<string, MyClass>>(sp => input => new MyClass(input, sp));方案三:属性注入(不推荐,仅作备选)
如果无法修改构造函数,可通过属性注入获取服务,需手动完成注入步骤:public class MyClass { // 定义可注入的属性 public SomeRequiredService RequiredService { get; set; } public MyClass(string someRandomInput) { // 构造逻辑 } }创建实例后,从DI容器获取服务并赋值:
var myClass = new MyClass("随机输入"); myClass.RequiredService = serviceProvider.GetRequiredService<SomeRequiredService>();
内容的提问来源于stack exchange,提问作者Hamid Z
相关产品推荐
相关产品推荐

