C# 指定要使用的 Unity IoC 容器的构造函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2162061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:03:11  来源:igfitidea点击:

Specify constructor for the Unity IoC container to use

c#.netunity-containerioc-container

提问by stiank81

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?

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

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.

具体来说,我有一个类似于以下带有两个构造函数的 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;
    }
}

This obviously fails as it can't create the SomeValueObject - not knowing what to inject to its string parameter. The error it gives is:

这显然失败了,因为它无法创建 SomeValueObject - 不知道向其字符串参数注入什么。它给出的错误是:

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)

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

The container registration:

容器注册:

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

And the resolving:

并解决:

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

采纳答案by Mark Seemann

Register it like this instead:

像这样注册它:

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

You can add the LifetimeManager as well using an overload of the RegisterType method.

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

That said, when modeling for DI, your life will be much easier if you have unambiguous contructors (i.e. no overloaded constructors).

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

回答by Diadistis

Multiple-Constructor Injection Using an Attribute

使用属性的多构造函数注入

When a target class contains more than one constructor with the same number of parameters, you must apply the InjectionConstructor attributeto the constructor that the Unity container will use to indicate which constructor the container should use. As with automatic constructor injection, you can specify the constructor parameters as a concrete type, or you can specify an interface or base class for which the Unity container contains a registered mapping.

当目标类包含多个具有相同数量参数的构造函数时,您必须将 InjectionConstructor 属性应用于 Unity 容器将用于指示容器应使用哪个构造函数的构造函数。与自动构造函数注入一样,您可以将构造函数参数指定为具体类型,也可以指定 Unity 容器包含已注册映射的接口或基类。

回答by Anton Gogolev

By default, Unity chooses a constructor with maximum number of arguments. To override this, decorate required constructor with InjectionConstructorAttribute.

默认情况下,Unity 选择具有最大参数数量的构造函数。要覆盖它,请使用InjectionConstructorAttribute装饰所需的构造函数。

回答by Chris Marisic

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.

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

What you most likely should do is register a default object of SomeValueObject that the .Name property returns string.Emptyinstead.

您最有可能做的是注册 SomeValueObject 的默认对象,该对象由 .Name 属性返回string.Empty