7

我使用Ninject MVC3(版本3.0.0.0)爲我的ASP.Net MVC3應用程序安裝使用NuGet包依賴注入。Ninject依賴注入與Asp.Net MVC3或MVC4

這裏是在Global.asax變化:

public class MvcApplication : NinjectHttpApplication 
{ 
    public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
    } 

    public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
     routes.IgnoreRoute("favicon.ico"); 
     routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" }); 

     routes.MapRoute(
      "Default",            // Route name 
      "{controller}/{action}/{id}",       // URL with parameters 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
     ); 
    } 


    protected override IKernel CreateKernel() 
    { 
     var kernel = new StandardKernel(); 
     kernel.Bind<Func<IKernel>>().ToMethod(ctx =>() => new Bootstrapper().Kernel); 
     kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); 
     RegisterServices(kernel); 
     return kernel; 
    } 

    protected override void OnApplicationStarted() 
    { 
     base.OnApplicationStarted(); 

     AreaRegistration.RegisterAllAreas(); 
     RegisterGlobalFilters(GlobalFilters.Filters); 
     RegisterRoutes(RouteTable.Routes); 
    } 

    /// <summary> 
    /// Load your modules or register your services here! 
    /// </summary> 
    /// <param name="kernel">The kernel.</param> 
    private static void RegisterServices(IKernel kernel) 
    { 
     kernel.Bind<IUserRepository>().To<UserRepository>(); 
     kernel.Bind<IUserService>().To<UserService>(); 
     kernel.Bind<ICommonRepository>().To<CommonRepository>(); 
     kernel.Bind<ICommonService>().To<CommonService>(); 
    } 
} 

但它提供了以下錯誤,雖然我有我的HomeController參數的構造函數:

System.NullReferenceException: Object reference not set to an instance of an object. 

Generated: Wed, 28 Mar 2012 05:49:01 GMT 

System.InvalidOperationException: An error occurred when trying to create a controller of type 'MVC3.Web.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor. ---> System.NullReferenceException: Object reference not set to an instance of an object. 
    at Ninject.Planning.Bindings.BindingConfiguration.GetProvider(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Bindings\BindingConfiguration.cs:line 107 
    at Ninject.Planning.Bindings.Binding.GetProvider(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Bindings\Binding.cs:line 212 
    at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157 
    at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386 
    at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 
    at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source) 
    at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 197 
    at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 165 
    at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 114 
    at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96 
    at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 
    at System.Linq.Buffer`1..ctor(IEnumerable`1 source) 
    at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) 
    at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96 
    at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157 
    at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386 
    at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 
    at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source) 
    at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 197 
    at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 165 
    at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 114 
    at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96 
    at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 
    at System.Linq.Buffer`1..ctor(IEnumerable`1 source) 
    at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) 
    at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96 
    at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157 
    at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386 
    at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 
    at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source) 
    at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 197 
    at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 165 
    at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 114 
    at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96 
    at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() 
    at System.Linq.Buffer`1..ctor(IEnumerable`1 source) 
    at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) 
    at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96 
    at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157 
    at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386 
    at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 
    at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source) 
    at Ninject.Web.Mvc.NinjectDependencyResolver.GetService(Type serviceType) in c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectDependencyResolver.cs:line 56 
    at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) 
    --- End of inner exception stack trace --- 
    at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) 
    at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) 
    at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) 
    at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) 
    at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<BeginProcessRequest>b__2() 
    at System.Web.Mvc.SecurityUtil.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a() 
    at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) 
    at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) 
    at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust[TResult](Func`1 func) 
    at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) 
    at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) 
    at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

UPDATE:

以下是HomeController的代碼:

public class HomeController : Controller 
    { 
     #region Declaration 
     public ICommonService _commonService { get; set; } 
     #endregion 

     #region Constructor 

     public HomeController() 
     { 

     } 

     public HomeController(ICommonService commonService) 
     { 
      this._commonService = commonService; 
     } 
     #endregion 

     public ActionResult Index() 
     { 
      return View(); 
     } 

CommonService和CommonRepository的構造:

public class CommonService : ICommonService 
    { 
     #region Declaration 
     private readonly ICommonRepository _repository; 
     #endregion 

     #region Constructor 
     public CommonService(ICommonRepository repository) 
     { 
      this._repository = repository; 
     } 
     #endregion 

public class CommonRepository : ICommonRepository 
    { 
     #region Declaration 
     private DBContainer _context = new DBContainer(); 
     #endregion 

     #region Constructor 
     public CommonRepository() 
     { 

     } 
     #endregion 

我失去了任何其他的參考嗎?

+0

檢查你的無參數構造函數是否公開 – Bond 2012-03-28 07:24:22

+0

債券,是的,我把它作爲公共。 public HomeController() { } – Prasad 2012-03-28 07:30:29

+0

你可以共享有問題的控制器(沒有操作方法)嗎? – tpeczek 2012-03-28 07:52:07

回答

7

這是Ninject構造選擇如何運作:

  1. 如果構造函數有一個[進樣]屬性,它被使用。如果多個構造函數具有[Inject]屬性,則Ninject將引發NotSupportedException。
  2. 如果沒有構造函數具有[注入]屬性,則Ninject將選擇Ninject知道如何解決的最多參數。
  3. 如果沒有定義構造函數,Ninject將選擇默認的無參構造函數 。

就你而言,Ninject很可能不會選擇無參數的構造函數,因爲它相信他知道如何解析ICommonService。如果你想讓Ninject使用它或者進一步調查爲什麼ICommonService沒有被解析,請嘗試用[Inject]屬性修飾你的無參數構造函數。

+0

當我在無參數構造函數上使用[Inject]屬性時,它工作正常,但ICommonService沒有得到解決。 – Prasad 2012-03-28 09:39:54

+0

所以問題是Ninject無法構建ICommonService。我在您的RegisterServices方法(Global.asax)中看不到它的綁定。在最好的情況下,Ninject使用隱式自綁定,但它並沒有給出任何可以構建的東西。這項服務的確切類型是什麼,它應該解決什麼問題? – tpeczek 2012-03-28 09:55:11

+0

我曾嘗試在我的Global.asax的RegisterServices中添加ICommonService,但仍然沒有得到解決,只是更新了我的問題。 – Prasad 2012-03-28 10:03:26

1

引用從https://github.com/ninject/ninject/wiki/Injection-Patterns

主要DI圖案是構造器注入。當激活一個類型的實例時,Ninject將通過按順序應用以下規則來選擇要使用的類型的構造函數之一: -

如果構造函數具有[Inject]屬性,則會使用它(但如果您應用該屬性不止一個,Ninject會在運行時檢測到NotSupportedException)。

如果沒有構造函數具有[Inject]屬性,則Ninject將選擇Ninject知道如何解決的最多參數。

如果沒有定義構造函數,Ninject會選擇默認的無參數構造函數(假設有一個構造函數)。

+0

當我刪除無參數構造函數時,它會拋出「確保控制器具有無參數公共構造函數」錯誤 – Prasad 2012-03-28 10:58:40

2

如果您最近將MVC應用程序從.NET 4.0重定向到4.5或其他方式,則會得到完全相同的症狀。它通過引用目標的正確的.NET版本DLL來解決。

如果您使用的是Ninject,Ninject.MVC3和Ninject.Web.Common,那麼您將在其中找到所有.NET目標。

+0

謝謝!這樣做解決了我的問題。 – 2013-01-16 12:56:49