2013-02-12 9 views
9

Używam Ninjec, Ninject.Web.MVC i Ninject.Web.Commonnie pasujące Wiązania są dostępne, a typ nie jest self-Bindable w Ninject

Kiedy zacznę mvc aplikacji otrzymuję ten błąd wiążącego :

Co jest nie tak w mojej oprawie?

Error activating DbConnection

No matching bindings are available, and the type is not self-bindable.

Activation path:

4) Injection of dependency DbConnection into parameter existingConnection of constructor of type DbContext

3) Injection of dependency DbContext into parameter dbContext of constructor of type GenericRepository{User}

2) Injection of dependency IGenericRepository{User} into parameter repo of constructor of type HomeController

1) Request for HomeController

Suggestions:

1) Ensure that you have defined a binding for DbConnection.

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.

public interface IGenericRepository<T> where T : class 
{ 
} 

public class GenericRepository<T> : IGenericRepository<T> where T : class 
{ 
     public GenericRepository(TLPContext dbContext) 
     { 
      DbContext = dbContext; 
     } 

     protected TLPContext DbContext { get; private set; } 
} 

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

namespace TLP.App_Start 
{ 
    using Microsoft.Web.Infrastructure.DynamicModuleHelper; 
    using Ninject; 
    using Ninject.Web.Common; 
    using System; 
    using System.Web; 
    using TLP.DataAccess; 
    using TLP.DataAccess.Contract; 
    using TLP.DataAccess.Implementation; 

    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>(); 
      kernel.Bind<TLPContext>(); 
      kernel.Bind(typeof(IGenericRepository<>)).To(typeof(GenericRepository<>)); 
      return kernel; 
     } 
    } 
} 


[DbModelBuilderVersion(DbModelBuilderVersion.V5_0)] 
    public class TLPContext : DbContext 
    { 
     public TLPContext() 
      : base("DefaultConnection") 
     { 
      // We do not want implicit uncontrollable lazy loading, instead we use the explicit Load method 
      this.Configuration.LazyLoadingEnabled = false; 
     } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 

      // Primary key 
      modelBuilder.Entity<User>().HasKey(p => p.UserId); 
      modelBuilder.Entity<User>().Property(p => p.FirstName).HasMaxLength(30).IsRequired(); 
      modelBuilder.Entity<User>().Property(p => p.RegisteredAt).IsRequired(); 
     } 

     public DbSet<User> Users { get; set; } 
    } 

Odpowiedz

11

Ninjects szuka konstruktorów in the following order:

  1. Konstruktorzy oznaczone [Inject]
  2. Construtors z najbardziej parametru
  3. Domyślnie contructor

W twoim przypadku twój konstruktor TLPContext nie jest oznaczony [Inject], więc obowiązują 2. reguły, a Ninject spróbuje rozwiązać base class contructor, a następnie zgłasza wyjątek.

Więc można rozwiązać ten problem przez znakowanie konstruktora z InjectAttribute

[Inject] 
public TLPContext() 
    : base("DefaultConnection") 
{ 
    this.Configuration.LazyLoadingEnabled = false; 
} 

lub można specify the constructor metodą ToConstructor podczas rejestracji TLPContext:

kernel.Bind<TLPContext>().ToConstructor(_ => new TLPContext()); 
+0

To dziwne. Nigdy nie użyłem .ToConstructor(), aby uzyskać zastrzyk za pośrednictwem konstruktora. Nie chcę wprowadzać Ninject do mojego projektu DataAccess. Wypróbowałem twój kod i nic nie zmieniłem. Ale co ostatnio zapomniałem: Nie znaleziono źródła NinjectDependencyResolver.cs Dostaję też ... Jakąkolwiek wskazówkę? Ach, teraz to rozumiem. Korzystam z projektu WebApi zamiast z mvc tylko wcześniej. Wygląda na to, że Ninject działa tutaj inaczej ... – Elisabeth

+0

Co masz na myśli mówiąc "Nie znaleziono źródła NinjectDependencyResolver.cs"? Jak zainstalowałeś Ninject w swoim projekcie za pomocą nuget? – nemesv

+0

Zawsze używam nuget tak. bez ręcznego instalowania hehe – Elisabeth

2

Kiedyś miałem podobny problem. Używałem Ninject MVC i próbowałem utworzyć instancję kernel przy użyciu nowego ctorka StandardKernel i nie zadziałało.

Mój problem był punkt 3, które @Elisa wspomniano wcześniej: Ensure you have not accidentally created more than one kernel.

I rozwiązać go za pomocą bootstrapper.Kernel zamiast.

Powiązane problemy