.NET Core 3.1:如何在实现工厂中应用默认构造发现规则
问题描述
使用C#和.NET Core 3.1,现有类MyClass实现IMyClass,包含三个构造函数:
- 无参构造函数
- 接收
IDependency的构造函数 - 接收
string类型appSettings的构造函数
常规依赖注入配置下,服务提供商会按照选择参数最多且依赖已注册的构造函数的规则,实例化MyClass(IDependency dependency)。
需求:若配置中的设置存在且有效,则使用接收string的构造函数实例化MyClass;否则沿用默认的构造函数发现规则实例化。尝试通过工厂实现时遇到两个问题:
- 使用
ActivatorUtilities.CreateInstance传入服务提供者时,会优先匹配无参构造函数,而非默认规则选择的构造; - 先注册
IMyClass与MyClass的映射,再在工厂中调用sp.GetRequiredService<IMyClass>()会导致无限循环。
解决方案
最简洁的方式是将MyClass自身注册为独立服务,在IMyClass的工厂实现中复用DI对MyClass的构造选择逻辑:
- 注册
MyClass自身:让DI框架按照默认规则处理MyClass的构造函数选择 - 在
IMyClass的工厂中分支处理:配置有效时手动实例化带string参数的构造,否则直接从服务提供者获取MyClass实例
代码示例:
// 先注册MyClass,DI会自动选择参数最多且依赖可解析的构造函数 services.AddTransient<MyClass>(); // 注册IMyClass的工厂实现 services.AddTransient<IMyClass>(sp => { var config = sp.GetRequiredService<IConfiguration>(); string appSettingValue = config["YourSettingKey"]; // 验证配置是否存在且有效 if (!string.IsNullOrWhiteSpace(appSettingValue) && IsSettingValid(appSettingValue)) { // 配置有效,直接调用带string参数的构造函数 return new MyClass(appSettingValue); } else { // 配置无效,复用DI对MyClass的默认构造选择逻辑 return sp.GetRequiredService<MyClass>(); } }); // 自定义配置验证方法 bool IsSettingValid(string value) { // 示例:验证字符串长度,可替换为实际业务校验逻辑 return value.Length >= 3; }
方案优势
- 完全复用DI框架的默认构造函数发现规则,无需手动模拟复杂逻辑
- 避免无限循环:
IMyClass的工厂依赖的是MyClass而非自身,不会触发循环调用 - 代码简洁清晰,符合.NET Core DI的设计习惯
内容的提问来源于stack exchange,提问作者reynoldsbj
相关产品推荐
相关产品推荐

