.NET Core 9依赖注入动态创建实例及所需服务方案咨询
.NET Core中动态创建带依赖与运行时参数类实例的最佳实践
场景回顾
你有两个类MyClass和MyOtherClass,MyClass需要根据运行时参数动态创建MyOtherClass实例,且两者各自需要对应的ILogger<T>实例。当前你采用了注入ILoggerFactory来创建日志实例并手动初始化MyOtherClass的方案,同时考虑过直接通过DI容器获取MyOtherClass的方式。
现有方案的合理性确认
你当前使用的**方案2(注入ILoggerFactory)**是完全合理的:
ILoggerFactory由DI容器管理,通过它创建的ILogger<MyOtherClass>会自动继承全局日志配置(如过滤规则、输出格式),符合.NET Core日志系统的设计规范- 代码逻辑清晰,能灵活传入
var1、var2这类运行时参数,没有过度依赖DI容器的内部机制 - 实现成本低,不需要额外的DI注册配置
更优方案建议:使用工厂委托注入
如果希望更贴合DI设计原则、提升代码可测试性,可以采用工厂委托注入的方式,将MyOtherClass的创建逻辑委托给DI容器,同时保留传入运行时参数的灵活性:
步骤1:注册工厂委托到DI容器
在Startup/Program.cs的DI配置中,注册一个能接收运行时参数并创建MyOtherClass的委托:
// 注册委托:接收int和string参数,返回MyOtherClass实例 services.AddTransient<Func<int, string, MyOtherClass>>(sp => (var1, var2) => new MyOtherClass( sp.GetRequiredService<ILogger<MyOtherClass>>(), var1, var2));
步骤2:修改MyClass依赖注入工厂委托
调整MyClass的构造函数,注入上述工厂委托,替代直接使用ILoggerFactory:
public class MyClass { private readonly ILogger<MyClass> _logger; private readonly Func<int, string, MyOtherClass> _myOtherClassFactory; private Dictionary<string, MyOtherClass> _instances; // 注入ILogger<MyClass>和工厂委托 public MyClass(ILogger<MyClass> logger, int count, Func<int, string, MyOtherClass> myOtherClassFactory) { _logger = logger; _myOtherClassFactory = myOtherClassFactory; _instances = new Dictionary<string, MyOtherClass>(); // 修正原代码中SeatMap的笔误 } public void Operate(string id, int var1, string var2) { if (!_instances.TryGetValue(id, out var instance)) { // 通过工厂委托创建实例,无需手动处理日志依赖 instance = _myOtherClassFactory(var1, var2); _instances.Add(id, instance); } // 执行后续操作 } }
该方案的优势
- 解耦性更强:
MyClass无需知晓MyOtherClass的构造细节,仅依赖抽象的工厂委托,符合依赖倒置原则 - 可测试性提升:单元测试时可以轻松mock工厂委托,无需依赖真实的
ILoggerFactory或DI容器 - 扩展性更好:如果后续
MyOtherClass增加新的依赖,仅需修改DI注册的委托逻辑,MyClass代码无需改动
关于方案1的说明
直接使用GetRequiredService<MyOtherClass>()无法直接处理运行时参数——DI容器默认只能解析预先注册的依赖,无法动态传入构造函数中的运行时参数,因此该方案不适用当前场景。
内容的提问来源于stack exchange,提问作者khteh
相关产品推荐
相关产品推荐

