20

So after much screwing around I finally got Ninject wired in and compiling in my MVC4 application. The problem I was running into is the IDependencyScope interface no longer exists from what I can tell and the System.Web.Http.Dependencies namespace was done away with.

So, my problem now is I have everything wired in and upon running the application I get:

    Sequence contains no elements

    [InvalidOperationException: Sequence contains no elements]
   System.Linq.Enumerable.Single(IEnumerable`1 source) +379
   Ninject.Web.Mvc.NinjectMvcHttpApplicationPlugin.Start() in c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectMvcHttpApplicationPlugin.cs:53
   Ninject.Web.Common.Bootstrapper.<Initialize>b__0(INinjectHttpApplicationPlugin c) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:52
   Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map(IEnumerable`1 series, Action`1 action) in c:\Projects\Ninject\ninject\src\Ninject\Infrastructure\Language\ExtensionsForIEnumerableOfT.cs:31
   Ninject.Web.Common.Bootstrapper.Initialize(Func`1 createKernelCallback) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:53
   Ninject.Web.Common.NinjectHttpApplication.Application_Start() in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\NinjectHttpApplication.cs:81

Which I haven't been able to track down or even begin to fathom where it is coming from.

My standard Ninject methods inside the Global.asax.cs look as follows:

        protected override IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());
            kernel.Bind<IRenderHelper>().To<RenderHelper>();

            GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel));
            return kernel;
        }

        protected override void OnApplicationStarted()
        {
            base.OnApplicationStarted();
            AreaRegistration.RegisterAllAreas();
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
            BundleTable.Bundles.RegisterTemplateBundles();
        }

And my custom resolver:

public class NinjectDependencyResolver : IDependencyResolver
{
    private readonly IKernel _kernel;

    public NinjectDependencyResolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    public object GetService(Type serviceType)
     {
         return _kernel.TryGet(serviceType);
     }

     public IEnumerable<object> GetServices(Type serviceType)
     {
         try
         {
             return _kernel.GetAll(serviceType);
         }
         catch (Exception)
         {
             return new List<object>();
         }
     }

     public void Dispose()
     {
         // When BeginScope returns 'this', the Dispose method must be a no-op.
     }
}

Any insight here would be greatly appreciated. I've spent far too much time already trying to get any DI framework wired into the latest MVC4 RC running on .NET 4.5 and have now just reached my tolerance level for things just not working at all..

Edit #1 A little further research digging around in github the ExtensionsForIEnumerableOfT.cs doesn't help much:

https://github.com/ninject/ninject/blob/master/src/Ninject/Infrastructure/Language/ExtensionsForIEnumerableOfT.cs

And possibly if I had wrote it myself I would begin to understand this but Bootstrapper.cs doesn't help too much either.

https://github.com/ninject/Ninject.Web.Common/blob/master/src/Ninject.Web.Common/Bootstrapper.cs

Hoping these details will make it easier for any of you who might have more experience with Ninject.

Edit #2 The error encountered is specifically in NinjectMvcHttpApplicationPlugin.cs:

The offending line is:

ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());

Which lives in the following method:

public void Start()
{
    ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());
    DependencyResolver.SetResolver(this.CreateDependencyResolver());
    RemoveDefaultAttributeFilterProvider();
}

The ModelValidatorProviders collection contains 2 elements: {System.Web.Mvc.DataErrorInfoModelValidatorProvider} {System.Web.Mvc.ClientDataTypeModelValidatorProvider}

And it's trying to remove a single instance of:

System.Web.Mvc.DataAnnotationsModelValidatorProvider

Which apparently isn't loaded up in the ModelValidationProviders.Providers collection. Any ideas from here?

Resolution to Above Exception And Onto The Next

To resolve the issue in the ModelValidatorProviders I had to manually add an object it was expecting. So now my CreateKernel method looks like:

protected override IKernel CreateKernel()
{
    var kernel = new StandardKernel();
    kernel.Load(Assembly.GetExecutingAssembly());

    kernel.Bind<IRenderHelper>().To<RenderHelper>();
    kernel.Unbind<IDocumentViewerAdapter>();

    GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel));
    ModelValidatorProviders.Providers.Add(new DataAnnotationsModelValidatorProvider());
    FilterProviders.Providers.Add(new FilterAttributeFilterProvider());
    return kernel;
}

Now it runs and gets into the actual guts of Ninject but still has an issue, one that makes no sense yet again:

Exception Details: Ninject.ActivationException: Error activating IntPtr
No matching bindings are available, and the type is not self-bindable.
Activation path:
 3) Injection of dependency IntPtr into parameter method of constructor of type Func{IKernel}
 2) Injection of dependency Func{IKernel} into parameter lazyKernel of constructor of type HttpApplicationInitializationHttpModule
 1) Request for IHttpModule

Suggestions:
 1) Ensure that you have defined a binding for IntPtr.
 2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
 3) Ensure you have not accidentally created more than one kernel.
 4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
 5) If you are using automatic module loading, ensure the search path and filters are correct.
VulgarBinary
  • 3,520
  • 4
  • 20
  • 54
  • Anyone gunning for a google search answer will likely not get it but you're welcome to try. I've read every article I could find through my own searches through the first 10 pages on google. Nothing has yielded any insight yet on what I possibly could be doing wrong. – VulgarBinary Jul 13 '12 at 12:30
  • I have installed the Ninject.MVC3 nuget package in my MVC4 application and DI just worked out of the box. Could that be something to try? – Wouter de Kort Jul 13 '12 at 13:05
  • Same here, MVC4 and the Ninject.MVC3 package works a treat... Although on .NET 4, not 4.5... – Dean Ward Jul 13 '12 at 13:10
  • I think that's the rub here... something changed in the System.Web.Http namespace and the Dependencies namaespace was removed. IDependencyResolver now lives inside System.Web.Http.Services not under Dependencies. – VulgarBinary Jul 13 '12 at 13:30
  • 2
    Hi, it always helps to let the title briefly show what the question is. – Gert Arnold Jul 14 '12 at 21:14

8 Answers8

18

Ok after beating my head against the wall for far too long I figured out what was going on. The default project type for MVC4 running on .NET 4.5 had a reference to the original RC version of System.Web.Http instead of the updated version.

Namespaces were missing, objects didn't exist, life was not good.

Steps for resolution:

  1. Remove your reference to System.Web.Http in your MVC4 project
  2. Add Reference -> System.Web.Http
  3. Delete all work arounds you put in to get the old garbage version of System.Web.Http to work
  4. Reapply standard process to wire in Ninject.

    HOWEVER, the error of:

    Exception Details: Ninject.ActivationException: Error activating IntPtr No matching bindings are available, and the type is not self-bindable. Activation path: 3) Injection of dependency IntPtr into parameter method of constructor of type Func{IKernel} 2) Injection of dependency Func{IKernel} into parameter lazyKernel of constructor of type HttpApplicationInitializationHttpModule 1) Request for IHttpModule

    Suggestions: 1) Ensure that you have defined a binding for IntPtr. 2) If the binding was defined in a module, ensure that the module has been loaded into the kernel. 3) Ensure you have not accidentally created more than one kernel. 4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name. 5) If you are using automatic module loading, ensure the search path and filters are correct.

Update This was solved by updating MVC from MVC4 Beta to MVC4 RC.

VulgarBinary
  • 3,520
  • 4
  • 20
  • 54
  • I had the same error after upgrading my server to .NET 4.5. Your post got me thinking that there might be some old bin files hanging out after the publish. I deleted everything in the folder and re-published and all is well. – Crob Mar 21 '14 at 17:40
  • Glad this post helped out! – VulgarBinary Aug 05 '14 at 22:47
5

Check out the Pro ASP.NET MVC 3 book. I just ported this code over from MVC3 to MVC4 last night and works correctly. Page 322 to be exact.

What I don't see is where you are mapping your Interface to your concrete items.

Bind<ISomething>().To<Something>();

Add another constructor and add the method that calls your mapping;

public NinjectDependencyResolver() {
    _kernal = new StandardKernel();
    RegisterServices(_kernel);
}

public static void RegisterServices(IKernel kernel) {
    kernel.Bind<ISomething>().To<Something>();
}

Here's what a resolver could/should look like;

   public class NinjectDependencyResolver : IDependencyResolver {
    private IKernal _kernel;

    public NinjectDependencyResolver(){
        _kernal = StandardKernal();
        AddBindings();
    }

    public NinjectDependencyResolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    public object GetService(Type serviceType)
     {
         return _kernel.TryGet(serviceType);
     }

     public IEnumerable<object> GetServices(Type serviceType)
     {
        return _kernal.GetAll(serviceType);
     }

    public IBindingToSyntax<T> Bind<T>() {
      return _kernal.Bind<T>();
    }

     public static void RegisterServices(IKernel kernel){
      //Add your bindings here. 
      //This is static as you can use it for WebApi by passing it the IKernel
     }
}

Global.Asx -

Application_Start()

method

DependencyResolver.SetResolver(new NinjectDependencyResolver());

That's it.


UPDATED 11/14/2012

On a side note, if you're working with MVC WebAPI, you will want to use WebApiContrib.IoC.Ninject from nuget. Also, check out the "Contact Manager" in their samples asp.net.com. This helped to cleanup the implementation of Ninject

harriyott
  • 10,505
  • 10
  • 64
  • 103
anAgent
  • 2,550
  • 24
  • 34
  • And I've seen the blog post about that book. It works under .NET 4.0 not under .NET 4.5. Did you run into IDependencyScope no longer existing or the namespace System.Web.Http.Dependencies no longer existing? If you did, we might be able to talk but giving me a link to an amazon book does me absolutely no good. Time is an issue here. – VulgarBinary Jul 13 '12 at 13:29
  • That's your .NET 4.0 answer, thanks for the update but still not much help. I saw a blog post off that book and believe me I tried. DependencyResolver doesn't exist anymore, the registration line now looks like: GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel)); I'll take off the -1 but still doesn't help me much. Upgrade your solution to target .NET 4.5 and update your System.Web.Http reference to 4.5 and then you'll be in the same boat as me. – VulgarBinary Jul 13 '12 at 13:48
  • Well, my intent was not to just provide you the code, but to help troubleshoot the issue a bit. Regardless of your assumptions - everyone overlooks things now and again. Teach a man to fish... and he sticks you in the eye with the hook..? =( – anAgent Jul 13 '12 at 13:49
  • I appreciate the help anAgent, just after spending a full day on this I'm a tad grumpy. I figured out the issue and it was with the initial RC version of the assemblies loaded in the MVC4 project. They are just flat out wrong. Updating the reference fixes the issue and now I have to delete all the work arounds I've been putting in place for the past 14 hours... I'm tired... and pissy and my Binding calls were in there... so came off a tad meaner than I should have. My apologies. – VulgarBinary Jul 13 '12 at 13:55
4

Just delete NinjectWebCommon.cs file from your project (it is in App_Start folder). and everything should be working.

Source: http://mlindev.blogspot.com.au/2012/09/how-to-implement-dependency-injection.html

1_bug
  • 5,505
  • 4
  • 50
  • 58
  • 1
    Works for me. A reference from official ninject repository issues: https://github.com/ninject/ninject.web.mvc/issues/24#issuecomment-45170797 – Igor Lizunov May 23 '16 at 04:28
1

When you will install latest Ninject.MVC3 from NuGet package we find following code on top of the NinjectWebCommon.cs file:

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

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

in this case we dont need to register ninject explicitly in global.asax

I found a good content on using Ninject with MVC 4 here

harriyott
  • 10,505
  • 10
  • 64
  • 103
  • 1
    @harriyott Found it on the Internet Wayback Machine: https://web.archive.org/web/20130722154409/http://www.dotnetfever.com/implementing-dependency-injection-in-asp-net-mvc-4-using-ninject-di-container/ – maracuja-juice Jan 22 '18 at 07:53
0

I tend to keep my Ninject bootstrapping in a separate project. In order to use the .InRequestScope() extension method of IBindingInSyntax<T>, I had added via Nuget the Ninject.Web.Common library. Alas, this library includes the app_start bootstrapper, resulting in duplicate NinjectWebCommon classes and attachment via WebActivator (1 in said project and 1 in the MVC project itself).

I deleted the duplicate App_Start folder from my bootstrap project, and this solved it.

Frederik Struck-Schøning
  • 12,981
  • 8
  • 59
  • 68
0

I have come across the same issue not quite sure what has fixed after below changes

added Ninject.MVC4 to project

deleted NinjectWebCommon.cs (the generated file, as the integration already exists in global.ascx.cs file)

Naga
  • 2,368
  • 3
  • 23
  • 33
0

I am using DD4T, and encountered same error.

After confirming that all packages are installed by nuget package manager, I found that some of the DLLs/references were missing (newtonsoft etc):

Then, after re-installing Newtonsoft.Json (to re-install package use following command in Nuget Package Manager:Update-Package –reinstall Newtonsoft.Json), and putting netrtsn.dll from Tridion Deployer bin, I got this error - "Sequence contains no elements" with exactly same stack trace as given in this question.

Thanks to Naga, for providing this resolution deleted NinjectWebCommon.cs (the generated file, as the integration already exists in global.ascx.cs file), and wohooooo!!!! all errors resolved, Tridion + MVC4 = DD4T is running fine now.

0

I have also had this problem when I used nuget to install Ninject.MVC4 in a project referenced by my actual MVC website project.

The trouble is that the NinjectWebCommon.cs file automatically installed in the App_Start directory of the referenced project conflicts with the (actual, useful) one installed in my website project. Removing the NinjectWebCommon.cs file from the referenced project resolves the error.

fordareh
  • 2,923
  • 2
  • 26
  • 39