2012-09-07 155 views
36

UPDATE定義無參數的構造函數 - 請看看我的答案爲解決方案的這個問題ASP.NET MVC 4 + Ninject MVC 3 =此對象

一個鏈接,並解釋我們開始之前,我知道這是一個非常普遍的問題,我一直在使用Ninject的許多衛星沒有問題,但現在它出現了,我找不出一個修復。另外,不,Google和SO迄今爲止的結果都沒有幫助我。

因此,考慮下面的代碼位上一個非常,非常,非常簡單的原型ASP.NET MVC 4從Visual Studio 2012在Windows Server 2008 R2的項目運行:

public class DefaultController : Controller { 
    private IGroupPrincipalRepository GroupPrincipalRepository { get; set; } 

    [Inject] 
    public DefaultController(
     IGroupPrincipalRepository groupPrincipalRepository) { 
     this.GroupPrincipalRepository = groupPrincipalRepository; 
    } 
} 

而這裏的NinjectWebCommon.cs RegisterServices方法:現在

kernel.Bind(typeof(IGroupPrincipalRepository)).ToConstructor(
    c => 
     new GroupPrincipalRepository(new PrincipalContext(ContextType.Domain, "?", "?", "?", "?"))).InSingletonScope(); 

,這是怎麼了我的那個(在.NET 4中,但ASP.NET MVC 3)工作中使用Ninject和其他項目,據我所知,這是使一切工作所需的內容。那麼,爲什麼我突然變得沒有爲這個對象定義無參數的構造函數。例外?

UPDATE

下面是完整的NinjectWebCommon.cs文件:

[assembly: WebActivator.PreApplicationStartMethod(typeof(App_Start.NinjectWebCommon), "Start")] 
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(App_Start.NinjectWebCommon), "Stop")] 

namespace App_Start { 
    using System; 
    using System.DirectoryServices.AccountManagement; 
    using System.Repositories.ActiveDirectory; 
    using System.Web; 
    using Microsoft.Web.Infrastructure.DynamicModuleHelper; 
    using Ninject; 
    using Ninject.Web.Common; 

    public static class NinjectWebCommon { 
     private static readonly Bootstrapper bootstrapper = new Bootstrapper(); 

     public static void Start() { 
      DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); 
      DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); 
      bootstrapper.Initialize(CreateKernel); 
     } 

     public static void Stop() { 
      bootstrapper.ShutDown(); 
     } 

     private static IKernel CreateKernel() { 
      var kernel = new StandardKernel(); 
      kernel.Bind<Func<IKernel>>().ToMethod(ctx =>() => new Bootstrapper().Kernel); 
      kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); 

      RegisterServices(kernel); 
      return kernel; 
     } 

     private static void RegisterServices(
      IKernel kernel) { 
      kernel.Bind(typeof(IGroupPrincipalRepository)).ToConstructor(
       c => 
        new GroupPrincipalRepository(new PrincipalContext(ContextType.Domain, "", "", "", ""))).InSingletonScope(); 
     } 
    } 
} 

更新 - 請大家看我的回答對解決方案的鏈接,並解釋了這個問題

+2

你在哪裏創建你的DependecyResolver並覆蓋默認值? – Josh

+0

我以爲這就是'NinjectWebCommon.cs'文件正在做什麼,如果沒有,那麼我想答案是「沒有地方」。再一次,我的目標混亂,因爲我的其他項目以這種方式工作,我已經檢查了兩倍和三倍,以確保我沒有說謊... – Gup3rSuR4c

+0

Ninject.MVC包中有一個'NinjectMvcHttpApplicationPlugin',它負責'DependecyResolver'...所以它應該只是工作?你如何安裝Ninject.MVC?用Nuget? – nemesv

回答

27

好,我沒有一個確切的答案爲什麼的錯誤即將到來,但我知道誰是造成的,這是Visual Studio 2012.我在2012年的同一臺機器上安裝了Visual Studio 2010,2010年安裝了ASP.NET MVC 4,並且我將2010年的項目重新創建爲2010年逐字,字母的單詞。最終的結果是,2010年調試項目時一切正常,Ninject按照它應該注入的依賴關係。

2012年調試它的項目時,它只是出現了No parameterless constructor defined for this object異常。在2012年.NET 4.0和.NET 4.5之間重新定位並不會做任何事情。從NuGet重新安裝Ninject也無能爲力。我甚至將2010和2012項目都配置爲使用本地IIS服務器,以確保最終結果是一致的。

我打算假設Visual Studio 2012或Ninject存在一個錯誤。我的兩個項目之間有唯一的區別是,他們是從運行的IDE和2012年項目是都崩潰了所以這就是爲什麼我指着手指在Visual Studio中的一個2012年

UPDATE

夥計們。夥計們!我再次遇到了這個問題,並在另一個SO問題中找到了解決方案:Ninject + MVC3 is not injecting into controller

基本上,這是網絡上缺少的東西。配置這使它的工作:

<dependentAssembly> 
    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> 
    <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> 
</dependentAssembly> 

我猜這迫使框架了解IoC容器,它允許Ninject終於能夠綁定。雖然,我不禁想到Ninject NuGet包應該在Web.config中查找綁定重定向的存在並自動將其添加。這肯定會有助於在這個問題上發生大量的頭髮問題。

P.S.對那篇文章中的鼻涕進行投票,因爲它值得!

+0

我看到了同樣的問題。希望兩者中的一個(VS 2012或Ninject)能解決這個問題。 –

+9

我的mvc4項目不會缺少這一行,但它仍然不起作用。 – liang

+0

正是我所需要的! – Rowan

3

從NuGet獲得MVC3後,我得到了相同的錯誤消息。
我不知道你是否按照我的方式設置了項目設置,但是我的web.config是根據環境自動生成的。 NuGet的MVC將rows (<runtime>)添加到web.config,並且由於我的合併配置文件安裝不正確,這些行被刪除。

問候,

+1

我不得不將元素添加到我的網絡配置中。以及確保具有targetFramework =「4.5」屬性。這是我的運行時元素。 Michael

+0

喜歡@邁克爾,我需要以及增加運行時間爲assemblybinding元素。Ninject.MVC4 – dbd

47

我知道這是一個老問題,但似乎並沒有爲任何真正的答案和我周圍的問題,所以在這裏工作是我的解決方案:

創建自定義控制器工廠:

public class NinjectControllerFactory : DefaultControllerFactory 
{ 
    private IKernel ninjectKernel; 
    public NinjectControllerFactory(IKernel kernel) 
    { 
     ninjectKernel = kernel; 
    } 
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
    { 
     return (controllerType == null) ? null : (IController) ninjectKernel.Get(controllerType); 
    } 
} 

然後,如果你正在使用NinjectHttpApplication,以下行添加到OnApplicationStarted:

ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(Kernel)); 

如果您沒有使用NinjectHttpApplication,那麼在您創建內核並將它傳遞給新創建的內核的引用後,將該行添加到某處。

就是這樣。

+1

真棒!夥計,你剛纔救了我的一天。非常感謝!我花了時間試圖解決這個問題,並解決了這個問題。順便說一句,我真的很想知道爲什麼發生這種情況,你基本上用這個代碼做了什麼。 – rkrdo

+0

在我的例子中,我必須使用如下代碼:「DynamicModuleUtility.RegisterModule (NinjectHttpModule));「在NinjectWebCommon的Start方法中,如果我用你的消息替換NinjectWebCommon,我不知道該移動這個代碼的位置,如果我嘗試在global.asax中移動它,我會收到一個錯誤,我在開始註冊模塊的過程中已經晚了,這就是爲什麼Ninject的大個子向我暗示保持使用NinjectWebCommon的解決方案。 – Samuel

+0

這會導致ASP MVC5,Ninject3.2,Ninject.MVC3的警告:「請勿將Ninject用作服務定位器」。該解決方案看起來像一個解決方法。 – SandRock

0

我最近在從MVC 3移植到MVC 4的項目上對我的頭髮進行了幾個小時的測試。由於缺乏關於點的答案,我認爲它必須是我所做的,因爲看起來Ninject.MVC3 nuget包可以在MVC 4中正常工作 - 的確如此。

在我的情況下,我沒有完全升級MVC3項目。在遵循this guide之後,我有事情按預期工作。我的猜測是我錯過了一個程序集綁定重定向。

因此,如果您要將MVC 3項目升級到MVC 4,請使用Ninject並獲取無參數構造函數定義的錯誤,希望這會有所幫助。

0

由於所有以前的海報已經表明這導致了一些灰色頭髮。在我的情況下,我對參考文獻進行了「優化」。 Ninject。*的東西在那裏,但已經變得糟糕了。我刪除了所有的引用並清理了packages.conf manualli並再次添加了這些包 - 勝利!

1

這是一個骯髒的解決方案! 將這個

var type = typeof(Ninject.Web.Mvc.MvcModule); 

在AppStart的事件(或其他地方)的開頭

現在讓我來解釋一下這是什麼意思,如果有人沒有得到欺騙呢。 事情是我們的http應用程序類可以駐留在解決方案的任何地方。不僅在Web應用程序中。這是非常重要的 ,因爲asp.net編譯例程不同於通常的庫應用程序。它通過BuildManager helper熱切加載所有引用的庫,而通常clr不會從開始加載類型,除非直接使用它們。

現在讓我們回到我們的情況:Ninject.Web.Mvc作爲動態插件工作,在代碼中不需要任何提及。因此,如果它在Class庫中被引用導致Mvc.Dependancy初始化失敗,則不會被加載。

1

當ASP.NET 4.0/4.5使用Visual Studio 2012/2013時,問題似乎就會發生。在Web.config文件中,System.Web.Mvc的版本被設置爲4.0.0.0。它不起作用。

我的解決辦法是

  1. 刪除NinjectWebCommon.cs
  2. 複製代雷瓊的NinjectControllerFactory類到項目:

    public class NinjectControllerFactory : DefaultControllerFactory 
    { 
        private IKernel ninjectKernel; 
        public NinjectControllerFactory(IKernel kernel) 
        { 
         ninjectKernel = kernel; 
        } 
    
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
        { 
         return (controllerType == null) ? null : (IController) ninjectKernel.Get(controllerType); 
        } 
    } 
    
  3. 變化Global.asax的內容:

    public class MvcApplication : NinjectHttpApplication 
    { 
        protected override IKernel CreateKernel() 
        { 
         IKernel kernel = new StandardKernel(); 
    
         // kernel.Load(Assembly.GetExecutingAssembly()); 
    
         // kernel.Bind<ISomeClass>().To<SomeClass>(); 
    
         return kernel; 
        } 
    
        protected override void OnApplicationStarted() 
        { 
         AreaRegistration.RegisterAllAreas(); 
    
         WebApiConfig.Register(GlobalConfiguration.Configuration); 
         FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
         RouteConfig.RegisterRoutes(RouteTable.Routes); 
         BundleConfig.RegisterBundles(BundleTable.Bundles); 
    
         ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(Kernel)); 
        } 
    } 
    

    之後,你的注射應該工作。

0

我有同樣的問題,唯一對我有用的是將Web項目屬性中的「本地IIS Web服務器」更改爲「使用Visual Studio開發服務器」。

enter image description here

我不知道爲什麼,但我這樣做的時候,我NinjectWebCommon斷點hited。就像@Alex所說的那樣,Visual Studio 2012中的東西在每次構建應用程序時都不夠明亮,無法在NinjectWebCommon中執行代碼。也有可能是我沒有足夠的明白瞭解它如何在引擎蓋下工作。

我不喜歡我的解決方案,因爲我寧願使用我的本地IIS Web服務器,但目前,我有一個應用程序來創建和花費很多時間與這個$%?!!/bug..feature ..不確定。

+0

確保在你的'Web.config'中有''部分。我的項目使用本地IIS和該設置運行得很好。當然,從MVC 5.1版本開始,綁定重定向應該是'''。 – Gup3rSuR4c

0

這對我來說是通過添加一個通過Nuget到Ninject.Web.MVC的引用來解決的。

0

我嘗試了所有這些解決方案,但都沒有成功。

這就是我解決它的方法: 刪除了所有我的臨時asp.net文件。完成此操作後,我收到了新的配置錯誤。我修好了他們。最後一個,真正的錯誤出來了:新的Bootstrapper()試圖加載一個ninject DLL的舊版本。 刪除所有ninject軟件包。 逐個安裝ninject nuget軟件包,確保安裝正確的版本。

0

我試圖用MVC 5設置Ninject。最後,我必須首先使用控制器工廠的解決方案,然後使用綁定重定向的解決方案。之後,所有的工作如預期。使用本地IIS服務器。

+1

我現在正在開發的項目是MVC 5(5.1.2),我不必使用控制器工廠。我只有綁定重定向,它都可以很好地工作。我也使用本地IIS服務器。我確實將Ninject代碼從MVC項目中分離出來,然後分解到它自己的項目中。 – Gup3rSuR4c

1

整件事只是荒謬的,我轉而使用Autofac,厭倦了永遠無法將Ninject成功添加到項目中。 Web API,MVC4,MVC5都有問題。

對於MVC5人,使用Ninject MVC3,添加以下web.config中的應用水平:

<runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
      <dependentAssembly> 
       <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/> 
       <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/> 
      </dependentAssembly> 
      <dependentAssembly> 
       <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/> 
       <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/> 
      </dependentAssembly> 
      <dependentAssembly> 
       <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/> 
       <bindingRedirect oldVersion="1.0.0.0-5.1.0.0" newVersion="5.1.0.0"/> 
      </dependentAssembly> 
     </assemblyBinding> 
    </runtime> 
7

不要重新發明輪子,只是嘗試安裝,包裝Ninject.MVC3

+1

這是正確的答案。我做了安裝包Ninject.MVC5,它工作。 – VivekDev

+0

釘住它。只需卸載Ninject MVC 3,再次安裝,重建整個解決方案,運行並修復 –

0

我能夠通過從我的控制器構造函數中刪除#if #endif指令來解決MVC5 Web項目中的此問題。

0

快捷方式這一切:下載下面的NuGet Pacakges之一:

  • Ninject.MVC3
  • Ninject.MVC5

這將照顧綁定,你需要的。

0

我通過刪除Ninject MVC5並從Nuget安裝Ninject MVC3來修復我的問題。

MVC5 == Ninject.MVC5 
MVC4 == Ninject.MVC3 
MVC3 == Ninject.MVC3 

檢查引用中的System.Web.MVC版本以確定您當前正在使用哪個版本的MVC。