2010-01-29 53 views
33

我正在使用Unity IoC容器来解析我的对象。但是,我遇到了一个问题。当我有多个构造函数时 - Unity如何知道使用哪一个?当我有一个和一个没有时,它似乎使用带参数的那个。我可以明确告诉它使用哪个构造函数吗?指定Unity IoC容器使用的构造函数

具体来说,我有一个情况类似于下面的人类有两个构造函数。在这种情况下,我希望IoC容器使用默认构造函数 - 不带参数 - 但它选择带参数的构造函数。

public class SomeValueObject 
{ 
    public SomeValueObject(string name) 
    { 
     Name = name; 
    } 
    public string Name { get; set; } 
} 

public class Person 
{ 
    private string _name; 

    public Person() 
    { 
     _name = string.Empty; 
    } 

    public Person(SomeValueObject obj) 
    { 
     _name = obj.Name; 
    } 
} 

这显然失败了,因为它不能创建SomeValueObject - 不知道要注入到它的字符串参数。它给出的错误是:

解析依赖失败,type =“MyApp.Person”,name =“”。异常消息是:当前构建操作(构建键构建键[MyApp.Person,null])失败:尝试调用构造函数MyApp.Person(MyApp.SomeValueObject obj)时无法解析参数obj。 (策略类型BuildPlanStrategy,指数3)

容器登记:

Container.RegisterType<Person, Person>(new Microsoft.Practices.Unity.ContainerControlledLifetimeManager()); 

而解决:

var person = Container.Resolve<Person>(); 
+0

是不是IoC的使用接口? – Martin 2010-01-29 13:10:44

+3

当然,我主要是这么做的。但是这对问题没有影响。 – stiank81 2010-01-29 13:13:02

+0

@Martin许多程序员使用类并避免了制作接口的假通用性,然后只实现了它。它还可以避免在大多数企业应用程序中看到大量臭臭的IoC接线,但仍可以在需要时切换某些实施。 http://programmers.stackexchange.com/questions/133471/writing-testable-code-vs-avoiding-speculative-generality – 2015-12-14 11:57:38

回答

46

注册像这样代替:

container.RegisterType<Person>(new InjectionConstructor()); 

您可以添加LifetimeManager以及使用RegisterType方法的重载。

也就是说,当为DI建模时,如果您有明确的构造函数(即没有重载的构造函数),您的生活会容易得多。

+0

你引用了哪些重载? – Casey 2014-03-25 15:17:21

+0

@Casey ...我相信空的构造函数。 – granadaCoder 2015-11-02 20:12:17

+0

由于没有针对InjectionConstructor的参数,它正在调用Person的空构造函数。如果代码是'新的InjectionConstructor(新的SomeValueObject(“John Smith”))',那就会调用(其他)Person构造函数,其中“other”构造函数是使用SomeValueObject对象/参数的构造函数。 – granadaCoder 2016-09-13 20:49:29

4

Multiple-Constructor Injection Using an Attribute

当目标类包含多于 一个构造函数w第i个参数相同数量的 ,必须应用 InjectionConstructor属性到 构造的统一容器 将用来指示容器应使用哪个构造 。如同 自动构造注射,你可以 指定构造参数 作为具体类型,或可以指定 为其 统一容器包含 注册映射的接口或基类。

22

默认情况下,Unity选择具有最大参数个数的构造函数。为了覆盖这个,用InjectionConstructorAttribute修饰所需的构造函数。

+4

我们应该提到装饰构造函数将组件连接到Unity作为它的IoC容器。在注册期间处理规范可能更可取,因此组件不需要参考Unity,因此如果需要,可以将不同的IoC交换出去。 – 2016-03-08 22:11:42

0

我真的必须指出在这种情况下使用依赖注入的方式是错误的。容器应该能够在构造上注入SomeValueObject。

你最可能应该做的是注册SomeValueObject的默认对象。而名称属性返回string.Empty

+0

也许我的简单例子是有点关闭,但实际代码中需要两个不同的构造函数..谢谢你提到。 – stiank81 2010-01-29 18:17:50

+0

如果你还没有写过它? – Casey 2014-03-25 15:06:11

相关问题