You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 3.1:如何在实现工厂中应用默认构造发现规则

问题描述

使用C#和.NET Core 3.1,现有类MyClass实现IMyClass,包含三个构造函数:

  • 无参构造函数
  • 接收IDependency的构造函数
  • 接收string类型appSettings的构造函数

常规依赖注入配置下,服务提供商会按照选择参数最多且依赖已注册的构造函数的规则,实例化MyClass(IDependency dependency)。

需求:若配置中的设置存在且有效,则使用接收string的构造函数实例化MyClass;否则沿用默认的构造函数发现规则实例化。尝试通过工厂实现时遇到两个问题:

  1. 使用ActivatorUtilities.CreateInstance传入服务提供者时,会优先匹配无参构造函数,而非默认规则选择的构造;
  2. 先注册IMyClass与MyClass的映射,再在工厂中调用sp.GetRequiredService<IMyClass>()会导致无限循环。
解决方案

最简洁的方式是将MyClass自身注册为独立服务,在IMyClass的工厂实现中复用DI对MyClass的构造选择逻辑:

  1. 注册MyClass自身:让DI框架按照默认规则处理MyClass的构造函数选择
  2. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 04:05:53