2009-06-22 70 views
2

我目前正在爲我使用的程序編寫一個開源SDK,並且我在內部使用一個IoC容器(NInject)來連接所有內部依賴項。在內部對象中使用IoC

我有一些標記爲內部的對象,因此我不會擠佔公共API,因爲它們只在內部使用,不應該被用戶看到,像工廠和其他對象。我遇到的問題是NInject無法創建內部對象,這意味着我必須將所有公開的內部對象標記爲公共API。

我的問題是:有沒有辦法解決這個問題,還是我這樣做都是錯的?

PS。我曾考慮過使用InternalsVisiableTo屬性,但我覺得這有點味道。

+0

如果它是一個開源的SDK,我想知道爲什麼你想阻止你的代碼的使用?我明白如果你想確保我們的SDK「用戶」不會錯誤地實例化對象,但對我來說,這更像是一種異味(SRP,LSP)。你能解釋一下你的約束嗎? – 2009-11-02 14:38:07

回答

3

快速瀏覽一下其他答案:它不」你看起來像是在做一些如此不同的事情,Ninject有一些根本性的錯誤,你需要修改或替換它。在許多情況下,你不能「直接去找內部」,因爲它們依賴於未解決的依賴注入;因此首先使用Ninject。這聽起來像你已經有一個內部的一組接口,這就是爲什麼提出的問題。

想法:直接在您的SDK或庫中使用Ninject的一個問題是,那麼您的用戶將不得不在他們的代碼中使用Ninject。這對你來說可能不是問題,因爲它是你的IoC選擇,所以你仍然要使用它。如果他們想要使用另一個IoC容器,那麼現在他們實際上有兩個正在運行的重複工作。更糟糕的是,如果他們想要使用Ninject v2並且你已經使用了v1.5,那麼這會讓情況變得非常複雜。

最好的情況:,如果你可以重構你的等級,所以他們得到他們通過依賴注入需要的,那麼這是最乾淨的,因爲庫代碼不需要任何 IoC容器的一切。該應用程序可以連接依賴關係,它只是流動。但這並不總是可能的,因爲有時庫類需要創建具有依賴性的實例,而這些依賴性無法通過注入來解決。

建議:CommonServiceLocator(和the Ninject adapter它)是專門爲這種情況(與依賴庫)設計。您針對CommonServiceLocator進行編碼,然後應用程序指定哪個DI/IoC實際支持該接口。

現在,您必須在應用程序中使用Ninject CommonServiceLocator,但CommonServiceLocator非常輕便,這有點痛苦。您的SDK /庫代碼只有使用相當乾淨的CommonServiceLocator。

0

我想你甚至不需要那個。 IoC是爲了公共資料。直接進入內部。

但是 - 這只是我的直覺......

0

創建二級,內部API,它是從外部API不同。你可能需要做手工分割...

-1

可以

  • 修改Ninject
  • 選擇不同的容器
0

我打算爲InternalsVisibleTo解決方案投票。完全沒有氣味,真的。這個屬性的要點是啓用你想要的行爲,而不是跳過各種精心設計的環節,讓事情沒有它,只需使用框架提供的功能來解決這個特定的問題。

我也建議,如果你想隱藏你從用戶容器的選擇,使用ILMerge到Ninject組件與SDK組件相結合,並應用/內在參數改變Ninject組件的可見性到內部,因此Ninject命名空間不會泄漏出您的庫(對不起,無法在線找到ILMerge文檔的鏈接,但下載時有一個doc文件)。還有這個關於將ILMerge集成到構建過程中的nice blog post