指定要使用的 Unity IoC 容器的构造函数
我正在使用 Unity IoC 容器来解析我的对象。但是,我遇到了一个问题。当我有多个构造函数时 - Unity 如何知道使用哪一个?当我有一个带参数和一个没有参数时,似乎使用带参数的一个。我可以明确告诉它使用哪个构造函数吗?
具体来说,我有一个类似于以下具有两个构造函数的 Person 类的情况。在本例中,我希望 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 - 不知道要向其字符串参数注入什么。它给出的错误是:
依赖关系解析失败,类型 =“MyApp.Person”,名称 =“”。异常消息是:当前构建操作(构建密钥 Build Key[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>();
I'm using the Unity IoC container for resolving my objects. However, I've run into an issue. When I have more than one constructor - how does Unity know which one to use? It seems to use the one with parameters when I have one with and one without. Can I explicitly tell it which constructor to use?
Specifically I had a case similar to the following Person class with two constructors. In this case I want the IoC container to use the default constructor - without parameters - but it chooses the one with parameters.
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;
}
}
This obviously fails as it can't create the SomeValueObject - not knowing what to inject to its string parameter. The error it gives is:
Resolution of the dependency failed, type = "MyApp.Person", name = "". Exception message is: The current build operation (build key Build Key[MyApp.Person, null]) failed: The parameter obj could not be resolved when attempting to call constructor MyApp.Person(MyApp.SomeValueObject obj). (Strategy type BuildPlanStrategy, index 3)
The container registration:
Container.RegisterType<Person, Person>(new Microsoft.Practices.Unity.ContainerControlledLifetimeManager());
And the resolving:
var person = Container.Resolve<Person>();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
像这样注册它:
您也可以使用 RegisterType 方法的重载来添加 LifetimeManager。
也就是说,在为 DI 建模时,如果您有明确的构造函数(即没有重载的构造函数),您的生活会容易得多。
Register it like this instead:
You can add the LifetimeManager as well using an overload of the RegisterType method.
That said, when modeling for DI, your life will be much easier if you have unambiguous contructors (i.e. no overloaded constructors).
默认情况下,Unity 选择具有最大参数数量的构造函数。要覆盖它,请使用 InjectionConstructorAttribute。
By default, Unity chooses a constructor with maximum number of arguments. To override this, decorate required constructor with InjectionConstructorAttribute.
使用属性的多构造函数注入
Multiple-Constructor Injection Using an Attribute
我真的必须指出,在这种情况下您使用依赖项注入的方式是错误的。容器应该能够在构造中注入 SomeValueObject。
您最可能应该做的是注册 SomeValueObject 的默认对象,.Name 属性将返回 string.Empty 。
I really have to point out the way you're using dependency injection in this instance is just wrong. The container should be able to inject SomeValueObject on the construction.
What you most likely should do is register a default object of SomeValueObject that the .Name property returns
string.Empty
instead.