2011-05-18 56 views

回答

5

此標記被標記的原因已過時並將在未來更改爲內部的原因在於,如果可以的話,人們傾向於將Ninject用作服務定位器。但Service Locator is an antipattern不應使用。由於我們不想提供有助於構建設計不當的軟件的功能,它將在未來被刪除。

如果這需要對代碼進行大量更改,則表示您的代碼正在遭受這種不良依賴注入的困擾,您應該將其更改爲更好的設計。

  1. 將您對內核的訪問限制爲最小值。在MVC中幾乎沒有任何情況需要除普通構造函數注入之外的其他東西。因此,我的第一個建議是在可能的情況下重構構造函數注入。
  2. 對於這些非常罕見的情況,您需要訪問內核來創建其他對象,您應該將工廠注入需要新實例的類並將內核注入此工廠(如果構造函數具有Kernel參數,將接收實例進行注入)。

如果你真的想留在服務定位器,即使幾乎每個人都會告訴你不要,你必須自己保留一個靜態引用。

+3

所有我的MVC相關的代碼,例如控制器有構造函數注入,所以沒有問題。但是在一種情況下,我必須實現一個自定義成員資格提供者,我想將IRepository傳遞給ctor。我可以找到ony解決方案在這裏http://stackoverflow.com/questions/5596441/inject-repository-to-custom-membership-provider-with-ninject。這就是我需要訪問Kernel的原因。你知道更好的方法嗎? – mahichR 2011-05-19 12:32:32

+0

查看我的答案;) – Guillaume86 2011-11-24 13:35:00

6

如果您有一個類(出於某種原因)需要從Ninject內核中檢索對象,則可以將該內核作爲注入的屬性/構造函數參數之一包含在該類中。從某種意義上說,這種模式更好,因爲您明確聲明特定的類正在使用內核,而不是像服務定位符模式那樣始終使用它。

這假定Ninject自動添加內核的實例綁定到自己。我知道它曾經這樣做,但如果不行,你可以手動添加綁定。

+0

將內核注入到我的類中將需要很多代碼更改並違反了我現有的應用程序體系結構。所以這不是和可選的。 (還是)感謝你的建議。 – mahichR 2011-05-18 17:25:10

+0

你可以發佈一些示例代碼,說明爲什麼注入IKernel會違反你的體系結構? – FMM 2011-07-13 15:41:26

+0

我認爲你應該把你的IKernel實例附加到對象管理的類上;肯定不是服務或業務邏輯。 – Dann 2011-07-18 16:01:42

0

您可以使用Common Service Locator作爲Ninject的服務位置掛鉤。通用服務定位器只允許您檢索對象,而不是注入已有的對象。當然,你可以繞過這個限制,但是你可以輕鬆創建一個靜態類來公開Ninject內核和引用,而不是BootStrapper。

2

在ASP.NET MVC 3中,我認爲DepedencyResolver是一種獲取服務定位器的簡單方法。

+2

從DependencyResolver獲取實例與ServiceLocator模式完全相同。它唯一應該使用的是創建控制器實例,並且只應由MVC框架調用,而不是由任何自己的代碼調用。 – 2011-07-13 15:46:04

+0

嗯,我已經回答了這個問題,並說這是服務的位置(而不是依賴注入),我不認爲我值得downvote – Guillaume86 2011-07-19 19:22:10