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