我使用您的代码和配置编写了一个小测试(并添加了缺失的ObjectC
):
public class ObjectA
{
public ObjectB InstanceB { get; set; }
}
public class ObjectB
{
public ObjectC InstanceC { get; set; }
}
public class ObjectC
{
}
考试:
[TestMethod]
public void ImplicitPropertyInjectionTest()
{
// Arrange
var container = new Container();
container.RegisterInitializer<object>(
i => container.InjectProperties(i));
// Act
var a = container.GetInstance<ObjectA>();
// Assert
Assert.IsNotNull(a.InstanceB);
Assert.IsNotNull(a.InstanceB.InstanceC);
}
测试成功并InstanceC
正确注入。我预计您的配置有问题,或者可能ClassC
无法创建。尝试ClassC
直接请求找出容器无法创建的原因:
container.GetInstance<ClassC>();
这条线可能会失败,这InstanceC
就是没有注入的原因。
这直接让我想到了以下几点:
像您一样调用RegisterInitializer<object>(instance => container.InjectProperties(instance))
是启用隐式属性注入的有效方法,但您应尽可能避免使用隐式属性注入,因为这会导致无法验证容器配置(container.Verify()
例如使用)。你已经注意到了这一点,因为InstanceC
被跳过了。相反,您应该尽可能使用构造函数注入。在此处查看有关以可以验证的方式编写代码的更多信息。
如果在某些场景下无法使用构造函数注入,最好使用显式属性注入,具体做法如下:
container.RegisterInitializer<ClassA>(a =>
{
a.InstanceB = container.GetInstance<ClassB>();
});
container.RegisterInitializer<ClassB>(b =>
{
b.InstanceC = container.GetInstance<ClassC>();
});
这会显式注入属性InstanceB
和InstanceC
,并且当无法注入属性时将无法构造。
可以在此处找到有关使用 Simple Injector 进行属性注入的更多信息。
最后一点。请注意,在隐式属性注入方面,所有容器的行为大致相同。因此,这并不是 Simple Injector 特有的。如果该容器支持此功能,它将跳过每个无法注入的属性。换句话说,所有容器都会默默地失败并继续,这通常不是你想要的。这意味着在使用默认启用隐式属性注入的容器时必须格外小心。