有没有办法使用 Bootstrap 文件和 Unity 容器在构造函数中注入 List<TypeA>?

Is there a way to inject List<TypeA> in a constructor using the Bootstrap file and Unity Container?

我正在使用 Unity 容器通过构造函数注入依赖项,我能够解析除对象列表之外的所有其他类型。 我尝试将类型注册为

container.RegisterType<IList<TypeA>,List<TypeA>>();

Bootstrap.cs 文件中。

当我尝试解析类型时,我遇到了这个异常:

The type List'1 has multiple constructors of length 1. Unable to disambiguate. At the time of the exception, the container was: Resolving System.Collections.Generic.List'1[Test.Models.TypeA],(none) (mapped from System.Collections.Generic.IList'1[Test.Models.TypeA], (none))

异常类型:InvalidOperationException

请建议我使用 Unity 容器注入对象列表。

AFAIK Unity 不会自动解析列表。我希望有人能够证明我是错的,并提供比这个更好的答案,但我就是这样做的。

比如说,您有一个名为 SomeService 的服务,它的构造函数中需要一个 IList<TypeA>。您需要做的第一件事是确保 ITypeA 的每个实例都注册为 命名实例 。最明智的做法是使用具体类型的名称作为名称。

container.RegisterType<ITypeA, TypeA1>(typeof(TypeA1).Name);
container.RegisterType<ITypeA, TypeA2>(typeof(TypeA2).Name);
container.RegisterType<ITypeA, TypeA3>(typeof(TypeA3).Name);

现在我们已经将类型注册为命名实例,我们需要注册 SomeService 并为其提供显式构造函数。

container.RegisterType<ISomeService, SomeService>(new InjectionConstructor(
    new ResolvedArrayParameter<ITypeA>(container.ResolveAll<ITypeA>().ToList())
));

列表的位置必须与构造函数声明中参数的位置相同。此外,必须明确提供所有参数

此外,该错误表明您的服务中有 多个 构造函数。这是一种称为 bastard injection 的反模式。它被认为是反模式的主要原因之一是 DI 容器经常在确定调用哪个构造函数时遇到问题,就像在这种情况下一样。

Unity 尝试使用参数最多的构造函数,然后解析并注入依赖项。由于 List<> 有 2 个带 1 个参数的构造函数,Unity 无法决定使用哪个构造函数。

您可以使用 InjectionFactory 告诉 Unity 如何解决此问题并使其使用 0 参数构造函数。

container.RegisterType<IList<TypeA>>(new InjectionFactory(x => new List<TypeA>()));