2012-04-10 184 views
2

我有一個ObjectA,它有一個屬性爲ObjectB,其屬性爲ObjectC,它們都在Simple Injector容器中。當我創建ObjectA時,我打電話InjectProperties,它加載了ObjectB。但是,此時,它不會在新創建的ObjectB內加載對ObjectC的引用;它不會執行我稱之爲對象的「深層積聚」。SimpleInjector不使用隱式注入屬性注入屬性

有沒有辦法啓用它?

編輯

我有一類對象:

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)); 

這將給ObjectBObjectA,但不會再注入ObjectCObjectB,在它解決了ObjectB

是否有解決方法?謝謝。

+0

簡單的注射器系統應該建立你的整個樹開箱,你可以發佈示例代碼,包括容器註冊。 您可能需要考慮使用構造函數注入,而不是在構造後顯式注入屬性。如果你不能改變這種模式,你可能需要考慮一個不同的IoC容器,比如Unity。這絕對支持後期施工深層積聚 – 2012-04-10 23:59:02

+0

請顯示這些類的代碼和註冊。我同意大多數羅伯特所說的,除了切換到Unity(尤其是Unity)之外。 – Steven 2012-04-11 04:28:03

回答

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>(); 
}); 

這明確地注入性質InstanceBInstanceC,並且將失敗施工時的屬性不能注射。

更多關於使用Simple Injector進行屬性注入的信息,請參閱here

最後一張紙條。請注意,所有容器在隱式屬性注入方面的行爲大致相同。所以這不是特定於簡單注射器。如果該容器支持該功能,則它將跳過無法注入的每個屬性。換句話說,所有的容器都會默默地失敗並繼續,這通常不是你想要的。這意味着在使用默認啓用隱式屬性注入的容器時,您必須格外小心。