如何在StructureMap中按ExplicitArguments类型选择构造函数?
解决DI容器中根据
ExplicitArguments自动选择构造函数的问题 看起来你遇到的核心问题是容器没有正确识别你通过ExplicitArguments传入的NetworkData实例,反而错误地尝试使用带有DefaultData参数的构造函数,进而因为DefaultData的构造参数缺失抛出异常。下面我来帮你一步步解决这个问题:
问题分析
从异常信息能明确看出:容器默认的构造函数选择逻辑没有优先匹配你显式传入的参数类型——它直接选中了优先级较高(比如声明顺序靠前)的Foo(IContainer, DefaultData)构造函数,完全忽略了你传入的NetworkData应该对应Foo(IContainer, NetworkData)这个构造函数。
解决方案:自定义构造函数选择器
你提到尝试过自定义IConstructorSelector但无法获取传入的参数类型,其实可以通过IContext对象拿到ExplicitArguments,然后根据里面的参数类型匹配最合适的构造函数。
1. 实现自定义构造函数选择器
public class ExplicitArgumentMatchingSelector : IConstructorSelector { public ConstructorInfo SelectConstructor(Type type, IContext context) { var explicitArgs = context.ExplicitArguments; // 如果没有显式参数, fallback到默认选择逻辑 if (explicitArgs == null || explicitArgs.Count == 0) { return new DefaultConstructorSelector().SelectConstructor(type, context); } // 获取当前类型的所有公共实例构造函数 var constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance); foreach (var ctor in constructors) { var parameters = ctor.GetParameters(); bool isMatch = true; foreach (var param in parameters) { // 跳过IContainer类型(容器可以自行解析) if (param.ParameterType == typeof(IContainer)) { continue; } // 检查显式参数中是否包含当前参数的类型 if (!explicitArgs.ContainsKey(param.ParameterType)) { isMatch = false; break; } } // 找到完全匹配的构造函数,直接返回 if (isMatch) { return ctor; } } // 如果没有找到匹配的,使用默认选择器 return new DefaultConstructorSelector().SelectConstructor(type, context); } }
2. 注册自定义选择器到容器
在创建容器实例后,替换默认的构造函数选择器:
var container = new Container(); // 替换为我们的自定义选择器 container.Options.ConstructorSelector = new ExplicitArgumentMatchingSelector(); // 正常传入显式参数 ExplicitArguments args = new ExplicitArguments(); args.Set(new NetworkData(new decimal(1.3D), 'f')); var instance = container.GetInstance<Foo>(args); // 此时instance.Location应该会是"NetworkData",符合预期
额外说明
- 异常中提到
DefaultData有一个带String和Int32参数的构造函数,但你提供的代码里DefaultData是无参的,这可能是你实际代码和示例的不一致——不过没关系,自定义选择器会跳过这个构造函数,直接匹配你传入的NetworkData对应的构造函数,从根源避免这个错误。 - 这个选择器是通用的,不仅适用于
Foo类,其他类只要有类似多构造函数+显式参数的场景,都可以复用。
内容的提问来源于stack exchange,提问作者Dominic Boexler
相关产品推荐
相关产品推荐

