Unity容器构造函数依赖注入:多参数解析问题求助
Unity容器解析多参数构造函数的问题解决
问题原因分析
你遇到的Unity.ResolutionFailedException错误,核心是错误地将字符串"SQL"直接传给了类型为IDataAccess的构造参数。Unity容器尝试把字符串转换成IDataAccess接口实例,但接口本身没有公共构造函数,自然无法实例化,导致报错。
你的错误代码中,new ParameterOverride("da", "SQL")是把注册的命名实例名称当作参数值传入,而不是传入IDataAccess的实际实例,这是对ParameterOverride用法的误解。
正确解决方案
下面提供两种可行的解决方式,针对ObjectBroker带IDataAccess和string双参数的构造函数场景:
方式一:注册时直接指定构造函数参数
先解析出IDataAccess的命名实例,再和字符串参数一起传入InjectionConstructor,完成ObjectBroker的注册:
//region #1 public interface IDataAccess { string GetDataBaseName(); } //endregion //region #2 public class SQL : IDataAccess { public string GetDataBaseName() { return "Data retrieved from SQL, Microsoft"; } } //endregion //region #3 public class ObjectBroker { private IDataAccess dataAccess; private string _param; // 修改为双参数构造函数 public ObjectBroker(IDataAccess da, string s) { dataAccess = da; _param = s; } public string GetDataBaseName() { return $"{dataAccess.GetDataBaseName()} | 参数值: {_param}"; } } //endregion //region #4 修正后的容器注册与解析 IUnityContainer iuContainer3 = new UnityContainer(); // 注册IDataAccess的命名实例"SQL" iuContainer3.RegisterType<IDataAccess, SQL>("SQL"); // 先解析出IDataAccess的实例 var dataAccessInstance = iuContainer3.Resolve<IDataAccess>("SQL"); // 创建带双参数的构造函数注入配置 var injectionConstructor = new InjectionConstructor(dataAccessInstance, "PSQL"); // 注册ObjectBroker的命名实例 iuContainer3.RegisterType<ObjectBroker>("SQL", injectionConstructor); // 解析并使用ObjectBroker var broker = iuContainer3.Resolve<ObjectBroker>("SQL"); Console.WriteLine(broker.GetDataBaseName()); //endregion
方式二:解析时动态指定参数(更灵活)
如果不想在注册时固定参数值,可以在解析ObjectBroker时,通过ResolverOverride动态指定依赖和参数:
// 容器初始化与注册 IUnityContainer iuContainer3 = new UnityContainer(); iuContainer3.RegisterType<IDataAccess, SQL>("SQL"); // 只需注册ObjectBroker,无需预先指定构造函数 iuContainer3.RegisterType<ObjectBroker>(); // 解析ObjectBroker时,指定两个参数: // 1. 用DependencyOverride指定IDataAccess使用命名实例"SQL" // 2. 用ParameterOverride指定string参数"s"的值为"PSQL" var broker = iuContainer3.Resolve<ObjectBroker>(new ResolverOverride[] { new DependencyOverride<IDataAccess>(iuContainer3.Resolve<IDataAccess>("SQL")), new ParameterOverride("s", "PSQL") }); Console.WriteLine(broker.GetDataBaseName());
关键注意点
ParameterOverride用于指定值类型/字符串类型的参数,不能直接用来指定接口类型的依赖;接口依赖应该用DependencyOverride,或者先解析出实例再传入。- 当构造函数有多个参数时,Unity会优先使用你通过
InjectionConstructor指定的构造逻辑,而不是自动推断。
内容的提问来源于stack exchange,提问作者Prasanth Sarath
相关产品推荐
相关产品推荐

