I have defined one interface and one class:
public interface IRepository
{
}
public class RoleRepository:IRepository
{
}
This should help accomplish what you are asking for.
First let us define two classes (InterfaceTypeDefinition and BindingDefinition).
InterfaceTypeDefinition holds information about a concrete type and its interfaces. The method IsOpenGeneric is define in the TypeExtensions class.
public class InterfaceTypeDefinition
{
public InterfaceTypeDefinition(Type type)
{
Implementation = type;
Interfaces = type.GetInterfaces();
}
///
/// The concrete implementation.
///
public Type Implementation { get; private set; }
///
/// The interfaces implemented by the implementation.
///
public IEnumerable Interfaces { get; private set; }
///
/// Returns a value indicating whether the implementation
/// implements the specified open generic type.
///
public bool ImplementsOpenGenericTypeOf(Type openGenericType)
{
return Interfaces.Any(i => i.IsOpenGeneric(openGenericType));
}
///
/// Returns the service type for the concrete implementation.
///
public Type GetService(Type openGenericType)
{
return Interfaces.First(i => i.IsOpenGeneric(openGenericType))
.GetGenericArguments()
.Select(arguments => openGenericType.MakeGenericType(arguments))
.First();
}
}
BindingDefinition holds information about the binding between a service and a concrete implementation.
public class BindingDefinition
{
public BindingDefinition(
InterfaceTypeDefinition definition, Type openGenericType)
{
Implementation = definition.Implementation;
Service = definition.GetService(openGenericType);
}
public Type Implementation { get; private set; }
public Type Service { get; private set; }
}
Second, let us implement an extension method that retrieves the necessary information.
public static class TypeExtensions
{
public static IEnumerable GetBindingDefinitionOf(
this IEnumerable types, Type openGenericType)
{
return types.Select(type => new InterfaceTypeDefinition(type))
.Where(d => d.ImplementsOpenGenericTypeOf(openGenericType))
.Select(d => new BindingDefinition(d, openGenericType));
}
public static bool IsOpenGeneric(this Type type, Type openGenericType)
{
return type.IsGenericType
&& type.GetGenericTypeDefinition().IsAssignableFrom(openGenericType);
}
}
These classes can now be used to initialize the bindings in the module.
public class RepositoryModule : NinjectModule
{
public override void Load()
{
var definitions = Assembly.GetExecutingAssembly().GetTypes()
.GetBindingDefinitionOf(typeof(IRepository<>));
foreach (var definition in definitions)
{
Bind(definition.Service).To(definition.Implementation);
}
}
}