我寫了使用你的代碼和配置一個小測試(並添加缺少的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。
最後一張紙條。請注意,所有容器在隱式屬性注入方面的行爲大致相同。所以這不是特定於簡單注射器。如果該容器支持該功能,則它將跳過無法注入的每個屬性。換句話說,所有的容器都會默默地失敗並繼續,這通常不是你想要的。這意味着在使用默認啓用隱式屬性注入的容器時,您必須格外小心。
簡單的注射器系統應該建立你的整個樹開箱,你可以發佈示例代碼,包括容器註冊。 您可能需要考慮使用構造函數注入,而不是在構造後顯式注入屬性。如果你不能改變這種模式,你可能需要考慮一個不同的IoC容器,比如Unity。這絕對支持後期施工深層積聚 – 2012-04-10 23:59:02
請顯示這些類的代碼和註冊。我同意大多數羅伯特所說的,除了切換到Unity(尤其是Unity)之外。 – Steven 2012-04-11 04:28:03