2013-02-12 1 views
9

J'utilise Ninjec, Ninject.Web.MVC et Ninject.Web.CommonAucune liaison de correspondance sont disponibles et le type ne sont pas auto-bindable dans Ninject

Quand je commence ma demande mvc je reçois cette erreur de liaison :

Qu'est-ce que je me trompe dans ma liaison?

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; } 
    } 

Répondre

11

Ninjects cherche des constructeurs in the following order:

  1. Constructors marqué avec [Inject]
  2. Construtors avec le paramètre le plus
  3. Par défaut contructor

Dans votre cas, votre constructeur n'est pas marqué avec [Inject] donc les règles 2. s'appliquent et Ninject essayera de résoudre le base class contructor et lancera l'exception.

Vous pouvez résoudre ce problème en marquant votre constructeur avec le InjectAttribute

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

Ou vous pouvez specify the constructor avec la méthode ToConstructor lors de l'enregistrement de votre TLPContext:

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

C'est étrange. Je n'ai jamais utilisé .ToConstructor() pour obtenir l'injection via le constructeur. Je ne veux pas introduire Ninject dans mon projet DataAccess. J'ai essayé votre code et ça ne change rien. Mais ce que j'ai oublié la dernière fois: NinjectDependencyResolver.cs source introuvable J'ai aussi ... Tout indice? Ah maintenant je comprends. J'utilise un projet WebApi au lieu du mvc seulement avant. Semble Ninject fonctionne différemment ici ... – Elisabeth

+0

Que voulez-vous dire sur "NinjectDependencyResolver.cs source introuvable"? Comment avez-vous installé Ninject dans votre projet avec nuget? – nemesv

+0

J'utilise toujours nuget oui. pas d'installation manuelle hehe – Elisabeth

2

J'ai déjà eu le même problème. J'utilisais Ninject MVC et j'ai essayé d'instancier le kernel en utilisant le nouveau StandardKernel ctor, et ça n'a pas fonctionné.

Mon problème était le point 3 qui @Elisa mentionné plus haut: Ensure you have not accidentally created more than one kernel.

Je l'ai résolu à l'aide bootstrapper.Kernel à la place.

Questions connexes