我有一个ObjectA
,其中包含ObjectB
的属性,该属性具有ObjectC
的属性,这些属性都在Simple Injector容器中。当我创建ObjectA
时,我会在其上调用InjectProperties
,这会加载ObjectB
。但是,此时,它不会在新创建的ObjectC
中加载对ObjectB
的引用;它没有执行我称之为对象的“深度构建”。
有没有办法启用它?
修改
我有一个类对象A:
public class ObjectA
{
public ObjectB InstanceB { get; set; }
}
具有ObjectB
的属性:
public class ObjectB
{
public ObjectC InstanceC { get; set; }
}
所有已使用容器上的标准注册方法注册。要获得ObjectA
,我使用GetInstance<ObjectA>(),
,这很好,我还建立了一个初始化器来在创建时构建所有对象:
_container.RegisterInitializer<object>(i => _container.InjectProperties(i));
这会将ObjectB
注入ObjectA
,但在结算ObjectC
时不会ObjectB
注入ObjectB
。
有解决方法吗?感谢。
答案 0 :(得分:3)
我使用您的代码和配置编写了一个小测试(并添加了缺少的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
被跳过了。相反,你应该尽可能多地使用构造函数注入。请参阅有关编写代码的详细信息,以便对其进行验证here。
如果在某些情况下无法使用构造函数注入,则更喜欢使用显式属性注入,其操作如下:
container.RegisterInitializer<ClassA>(a =>
{
a.InstanceB = container.GetInstance<ClassB>();
});
container.RegisterInitializer<ClassB>(b =>
{
b.InstanceC = container.GetInstance<ClassC>();
});
这会明确注入属性InstanceB
和InstanceC
,并且在无法注入属性时将失败构造。
可以找到有关使用Simple Injector进行属性注入的更多信息here。
最后一点。请注意,在隐式属性注入方面,所有容器的行为大致相同。所以这不是Simple Injector特有的。如果该容器支持此功能,它将跳过无法注入的每个属性。换句话说,所有容器都将无声地失败并继续,这通常不是您想要的。这意味着在使用默认启用隐式属性注入的容器时必须格外小心。