從頭開始使用帶有 Ninject 2 的 ASP.NET MVC 2
我昨晚剛剛在一個新項目上做了文件-> 新項目。啊,綠色田野的氣味。
我正在使用剛剛發布的 ASP.NET MVC 2(即沒有預覽版或發布候選版,真實的東西),並認為我會開始使用帶有 MVC 擴展的 Ninject 2(也是發布版)。我下載了 MVC 擴展項目,在 VS2008Sp1 中打開它,在發布模式下建構它,然後進入 mvc2\build\release 文件夾並將 Ninject.dll 和 Ninject.Web.Mvc.dll 從那裡複製到我的庫文件夾中項目(這樣我就可以在原始碼管理中使用它們,並且始終在任何地方都有正確的版本)。我沒有包含相應的 .xml 文件 - 應該嗎?它們只是提供智能感知還是其他一些功能?我相信沒什麼大不了的。
無論如何,我遵循了我能找到的最新建議;我在 MVC2 項目中引用了 DLL,然後開始研究 Global.asax.cs。首先我讓它繼承自 NinjectHttpApplication。我刪除了 Application_Start() 方法,並改寫了 OnApplicationStarted() 。這是那個方法:
protected override void OnApplicationStarted() { base.OnApplicationStarted(); AreaRegistration.RegisterAllAreas(); RegisterRoutes(RouteTable.Routes); // RegisterAllControllersIn(Assembly.GetExecutingAssembly()); }而且我也聽從了 VS 的建議,實現了 CreateKernel 方法:
protected override Ninject.IKernel CreateKernel() { // RegisterAllControllersIn(Assembly.GetExecutingAssembly()); return new StandardKernel(); }就這些。沒有對項目進行其他修改。
您會注意到 RegisterAllControllersIn() 方法在上面的兩個地方被註釋掉了。我想我可以用三種不同的組合來執行它,所有這些組合都有它們時髦的副作用;
- 像上面一樣執行它。
然後,我看到了標準的“歡迎使用 ASP.NET MVC”頁面。但是,在瀏覽器中正確顯示此頁面後,VS 向我顯示了一個引發的異常。它拋出 NinjectControllerFactory.GetControllerInstance(),在 controllerType 參數中使用 NULL 值呼叫它。請注意,這是在呈現 /Home 頁面之後發生的 - 我不知道為什麼再次呼叫它,並且通過使用斷點,我已經確定 GetControllerInstance() 已為 HomeController 成功呼叫。為什麼這個新呼叫 controllerType 為空?我真的不知道。此時按 F5 將我帶回瀏覽器,那裡沒有任何抱怨。
- 在 CreateKernel() 中取消註釋 RegisterAllControllersIn() 方法
這就是東西真正開始變得時髦的地方。現在我收到 404 錯誤。有時我在 RegisterAllControllersIn() 行上也遇到了 ArgumentNullException,但這種情況非常罕見,而且我無法重現它。
- 取消註釋 OnApplicationStarted() 中的 RegisterAllControllers() 方法
(並將評論放回 CreateKernel() 中的評論)
導致行為與第 1 點完全相同。
因此,為了避免永遠繼續下去 - 是否有關於如何使用 Ninject 2(兩個非 beta 版本)設置 MVC 2 項目以獲得 Ninject 提供的控制器的確切分步指南?當然,然後我將開始提供一些實際的注入內容(如 ISession 對象和儲存庫、記錄器等),但我想我會先讓這個工作。
任何幫助將不勝感激!
(也發佈到 Ninject Google Group)
我覺得回答我自己的問題很骯髒,但為了任何可能陷入這個問題的人的利益……
這不是 Ninject 問題,實際上,這似乎是 Cassini(內置於 VS2k8 中的 Web 伺服器)的問題,它處理這些請求的方式與 IIS 處理它們的方式不同。基本原因是應用程序收到了對 favicon.ico 的請求,Cassini 將其發送到 MVC,而 Ninject 不知道如何處理它。
Ian Davis 在極短的時間內解決了這個問題,並且還建議在開發過程中添加一個忽略路徑來避免這個問題。只需將以下內容添加到您的路由配置中:
routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });希望這對某人有幫助!