Unity - 为啥 Resolve(ParameterOverride[]) 不使用预期的构造函数?
Posted
技术标签:
【中文标题】Unity - 为啥 Resolve(ParameterOverride[]) 不使用预期的构造函数?【英文标题】:Unity - Why isn't Resolve(ParameterOverride[]) using the expected constructor?Unity - 为什么 Resolve(ParameterOverride[]) 不使用预期的构造函数? 【发布时间】:2022-01-13 18:09:10 【问题描述】:我想将 IoD 与实现接口并具有带参数的构造函数的类一起使用。
界面:
public interface IUsefulClass
string InterestingInfo get; set;
string RelevantStuff get; set;
两个简单的属性,没什么好说的。
班级:
public class UsefulClass : IUsefulClass
public string InterestingInfo get; set;
public string RelevantStuff get; set;
public UsefulClass()
public UsefulClass(string p_strInterestingInfo)
InterestingInfo = p_strInterestingInfo;
public UsefulClass (string p_strInterestingInfo, string p_strRelevantStuff)
InterestingInfo = p_strInterestingInfo;
RelevantStuff = p_strRelevantStuff;
它有几个不同的构造函数,每个构造函数都以自己的方式设置属性。
另一个类的调用:
public void HereGoes()
IUnityContainer z_ucoContainer = new UnityContainer();
z_ucoContainer.RegisterType<IUsefulClass, UsefulClass>();
IUsefulClass z_objUsefulButEmpty = z_ucoContainer.Resolve<IUsefulClass>();
IUsefulClass z_objUsefulAndInteresting = z_ucoContainer.Resolve<IUsefulClass>(new ParameterOverride("p_strInterestingInfo", "This is interesting information"));
IUsefulClass z_objUsefulAndInterestingToo = z_ucoContainer.Resolve<IUsefulClass>(new ParameterOverride[] new ParameterOverride("p_strInterestingInfo", "This is very interesting information") );
IUsefulClass z_objUsefulInterestingAndRelevant = z_ucoContainer.Resolve<IUsefulClass>(new ParameterOverride("p_strInterestingInfo", "This is quite interesting information"), new ParameterOverride("p_strRelevantStuff", "More relevant stuff here"));
IUsefulClass z_objUsefulInterestingAndRelevantAsWell = z_ucoContainer.Resolve<IUsefulClass>(new ParameterOverride[] new ParameterOverride("p_strInterestingInfo", "This is possibly the most interesting information"), new ParameterOverride("p_strRelevantStuff", "Look for relevant stuff there") );
在测试和调试时,我发现所有五个变量在两个属性中都有null
。
再调试一番,发现每个Resolve()
都调用了无参数构造函数。
我尝试删除上述构造函数(当然还有设置 z_objUsefulButEmpty
的代码行):我收到 Unity.ResolutionFailedException 消息“解决失败并出现错误:无法为 RegMat_VM.Infrastructure.UsefulClass 选择构造函数” .
我看了又看(here 和 there 以及其他地方),但找不到我做错了什么。我怎样才能让它正常工作?
【问题讨论】:
【参考方案1】:解决办法是这样调用:
IUnityContainer z_ucoContainer = new UnityContainer();
z_ucoContainer.RegisterType<IUsefulClass, UsefulClass>();
z_ucoContainer.RegisterType<IUsefulClass, UsefulClass>("stringConstructor",new InjectionConstructor (typeof(string)));
z_ucoContainer.RegisterType<IUsefulClass, UsefulClass>("string2Constructor", new InjectionConstructor (typeof(string), typeof(string)));
IUsefulClass z_objUsefulButEmpty = z_ucoContainer.Resolve<IUsefulClass>();
IUsefulClass z_objUsefulAndInteresting = z_ucoContainer.Resolve<IUsefulClass>("stringConstructor",new ParameterOverride("p_strInterestingInfo", "This is interesting information"));
IUsefulClass z_objUsefulAndInterestingToo = z_ucoContainer.Resolve<IUsefulClass>("stringConstructor",new ParameterOverride[] new ParameterOverride("p_strInterestingInfo", "This is very interesting information") );
IUsefulClass z_objUsefulInterestingAndRelevant = z_ucoContainer.Resolve<IUsefulClass>("string2Constructor",new ParameterOverride("p_strInterestingInfo", "This is quite interesting information"), new ParameterOverride("p_strRelevantStuff", "More relevant stuff here"));
IUsefulClass z_objUsefulInterestingAndRelevantAsWell = z_ucoContainer.Resolve<IUsefulClass>("string2Constructor",new ParameterOverride[] new ParameterOverride("p_strInterestingInfo", "This is possibly the most interesting information"), new ParameterOverride("p_strRelevantStuff", "Look for relevant stuff there") );
这涉及到构造注入的知识。
当有多个构造函数时,可以使用InjectionConstructorAttribute
来装饰你唯一需要的构造函数。
当您需要同时使用multiple constructors
时,您需要命名它们并在解析时使用该名称。
有关命名构造函数的更一般用法,请参见下文:
using System;
using System.Collections.Generic;
using Unity;
using Unity.Injection;
using Unity.Resolution;
namespace ConsoleApp1
class Program
static void Main (string[] args)
IUnityContainer container = new UnityContainer();
container.RegisterType<IPeople, Swordsman>(new InjectionConstructor());//Unnamed default registration, the following default registration will overwrite the previous one
container.RegisterType<IPeople, Witch>("Witch");//Named registration
IPeople people=container.Resolve<IPeople>();//Resolve default objects
IPeople _witch =container.Resolve<IPeople>("Witch");//Specify the name resolution object
IEnumerable<IPeople> peoples=container.ResolveAll<IPeople>();//Get all registered named objects of IPeople in the container
people.ClassName = people.GetType().ToString();
_witch.ClassName = _witch.GetType().ToString();
var info1= people.ShowInfo();
var info2= _witch.ShowInfo();
foreach (var item in peoples)
item.ClassName = item.GetType().ToString();
Console.WriteLine(item.ShowInfo());
Console.WriteLine(info1);
Console.WriteLine(info2);
//Dealing with the case of multiple constructors:
container.RegisterType<IPeople, Swordsman>("SString",new InjectionConstructor(typeof(string)));
container.RegisterType<IPeople, Swordsman>("TString", new InjectionConstructor(typeof(string), typeof(string)));
var people2=container.Resolve<IPeople>("SString",new ParameterOverride("o" ,"hello"));
IPeople people3=container.Resolve<IPeople>("TString",new ParameterOverride ("o", "hello"),new ParameterOverride ("g", "world"));
Console.WriteLine(people2.ClassName);
Console.WriteLine(people3.ClassName + people3.ClassAge);
Console.ReadLine();
//People interface
public interface IPeople
string ClassName
get; set;
string ClassAge
get; set;
string ShowInfo ();
//Witch
public class Witch : IPeople
public string ClassName
get; set;
public string ClassAge
get; set;
public string ShowInfo ()
return string.Format("Witch:0", ClassName);
//Swordsman
public class Swordsman : IPeople
public string ClassName
get; set;
public string ClassAge
get;set;
public string ShowInfo ()
return string.Format("Swordsman:0", ClassName);
public Swordsman (string o)
ClassName = o;
//[InjectionConstructor]
public Swordsman ()
public Swordsman (string o, string g)
ClassName = o;
ClassAge = g;
输出:
【讨论】:
@Jean-DavidLanz 谢谢,一切都是为了更好地服务客户。以上是关于Unity - 为啥 Resolve(ParameterOverride[]) 不使用预期的构造函数?的主要内容,如果未能解决你的问题,请参考以下文章
使用Unity依赖注入的时候,最上层的类是Resolve还是New的问题
为啥链接到 Promise.resolve() 的 .then() 允许重新分配 const 声明?
为啥 Promise 构造函数需要一个在完成时调用 'resolve' 的函数,但 'then' 不需要 - 它返回一个值?
AIOHTTP with Graphql: TypeError: __init__() got an unexpected keyword argument 'resolve'。为啥会出现这个问题?