Reputation: 5461
I am building an application using Ninject and ASP.NET MVC 3. Is it possible with Ninject to supply a generic binding within a module like this:
Bind(typeof(IRepository<>)).To(typeof(SomeConcreteRepository<>));
EDIT: And then for a specific type , create a class that inherits from SomeConcreteRepository:
Bind(typeof(IRepository<Person>)).To(typeof(PersonConcreteRepository));
This throws an exception that multiple bindings are available. However, is there another approach to this? Are there other DI frameworks for .NET which support this behavior?
Upvotes: 0
Views: 670
Reputation: 800
public class ExtendedNinjectKernal : StandardKernel
{
public ExtendedNinjectKernal(params INinjectModule[] modules) : base(modules) { }
public ExtendedNinjectKernal(INinjectSettings settings, params INinjectModule[] modules) : base(settings, modules) { }
public override IEnumerable<IBinding> GetBindings(Type service)
{
var bindings = base.GetBindings(service);
//If there are multiple bindings, select the one where the service does not have generic parameters
if (bindings.Count() > 1 && bindings.Any(a => !a.Service.IsGenericTypeDefinition))
bindings = bindings.Where(c => !c.Service.IsGenericTypeDefinition);
return bindings;
}
}
Upvotes: 0
Reputation: 5461
A bit of a nasty fix but for the scenario at hand it works:
public class MyKernel: StandardKernel
{
public MyKernel(params INinjectModule[] modules) : base(modules) { }
public MyKernel(INinjectSettings settings, params INinjectModule[] modules) : base(settings, modules) { }
public override IEnumerable<IBinding> GetBindings(Type service)
{
var bindings = base.GetBindings(service);
if (bindings.Count() > 1)
{
bindings = bindings.Where(c => !c.Service.IsGenericTypeDefinition);
}
return bindings;
}
}
Upvotes: 1
Reputation: 1038850
You don't need the second line. Simply register the open generic types:
kernel.Bind(typeof(IRepository<>)).To(typeof(SomeConcreteRepository<>));
and later fetch a specific repository like this:
var repo = kernel.Get<IRepository<Person>>();
or you can also use a provider.
Upvotes: 3