给定一个包含多个构造函数的类 - 如何告诉Resolve使用哪个构造函数?
考虑以下示例类:
public class Foo
{
public Foo() { }
public Foo(IBar bar)
{
Bar = bar;
}
public Foo(string name, IBar bar)
{
Bar = bar;
Name = name;
}
public IBar Bar { get; set; }
public string Name { get; set; }
}
如果我想使用Resolve创建一个Foo类型的对象,Resolve将如何知道要使用哪个构造函数?我怎么能告诉它使用正确的呢?假设我有一个注册了IBar的容器 - 它会理解它应该支持构建者采用IBar吗?如果我也指定了一个字符串 - 它会使用(string, IBar)
构造函数吗?
Foo foo = unityContainer.Resolve<Foo>();
请忽略这样一个事实:如果这个类只有一个构造函数可能会更容易......
答案 0 :(得分:58)
当目标类包含多个构造函数时,Unity将使用具有应用了InjectionConstructor属性的构造函数。如果有多个构造函数,并且没有构造函数携带InjectionConstructor属性,Unity将使用具有最多参数的构造函数。如果有多个这样的构造函数(多于一个具有相同参数数量的“最长”),Unity将引发异常。
答案 1 :(得分:32)
注册类型时,可以指定要使用的构造函数:
container.RegisterType<Foo>(
new InjectionConstructor(
new ResolvedParameter<IBar>()));
以上代码来自内存,但这是一般原则。在这种情况下,我选择了采用IBar类型的单个参数的构造函数。
请忽略这样一个事实:如果这个类只有一个构造函数可能会更容易......
我不能忽视这一点。对于构造函数注入,歧义是一种设计气味。你基本上是在说:我真的不知道我是否关心这种依赖。
当然,Unity可能会为您解决这个问题,但是您将依赖于特定的容器行为,而不是正确设计您的API。 其他容器可能有不同的行为,因此如果您选择从Unity迁移到更好的容器,可能会出现细微的错误。
以DI-friendly, but container-agnostic方式编写代码会更安全。