How to bind Generic-type interfaces in Ninject

McGarnagle picture McGarnagle · Apr 20, 2012 · Viewed 19.5k times · Source

I'm fairly new to Ninject, and found myself stumbling when I came to implement a generic repository pattern. I want to bind a dependency IRepository<IEntityType> to a class ConcreteRepository<EntityType> where ConcreteRepository<T> implements IRepository<T> and EntityType implements IEntityType. I tried this:

kernel.Bind<IRepository<IEntityType>>().To<ConcreteRepository<EntityType>>();

...but Ninject won't take that because it doesn't know or care that EntityType implements IEntityType. How can I go about binding this dependency?

UPDATE

This is the error I'm getting:

Error 3 The type 'ICM.Dependency.Repository.ConcreteRepository' cannot be used as type parameter 'TImplementation' in the generic type or method 'Ninject.Syntax.IBindingToSyntax.To()'. There is no implicit reference conversion from 'ConcreteRepository<EntityType>' to 'IRepository<IEntityType>'.

SOLUTION

I still don't quite understand why my binding doesn't work, but evidently I was using generics incorrectly there. As such the solution doesn't really relate to NInject. I ended specifying the ConcreteRepository to explicitly connect IEntityType with TEntityType:

public class ConcreteRepository<TInterface, TEntity> : IRepository<TInterface> where TEntity : TInterface { ... }

Then the injection can be written as follows:

kernel.Bind<IRepository<IEntityType>>().To<ConcreteRepository<IEntityType,EntityType>>()

Answer

Not loved picture Not loved · Apr 20, 2012
kernel.Bind(typeof(IRepository<>)).To(typeof(SimpleRepository<>));

Take a look at my one if you want here: http://blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html i have binding examples

EDIT:

The error you are getting is saying that your concrete repository isnt an instance of the generic one you want to bind to, ie you will need to do this

public class ConcreteRepository<ConcreteEntity> : IRepository<IEntity>{}

not

public class ConcreteRepository<ConcreteEntity> : IRepository<ConcreteEntity>{}