This should help fulfill what you are asking for.
First we define two classes ( InterfaceTypeDefinition and BindingDefinition ).
InterfaceTypeDefinition contains information about a particular type and its interfaces. The IsOpenGeneric method IsOpenGeneric defined in the TypeExtensions class.
public class InterfaceTypeDefinition { public InterfaceTypeDefinition(Type type) { Implementation = type; Interfaces = type.GetInterfaces(); }
BindingDefinition contains binding information between a service and a specific 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; } }
Secondly, let's implement an extension method that extracts the necessary information.
public static class TypeExtensions { public static IEnumerable<BindingDefinition> GetBindingDefinitionOf( this IEnumerable<Type> 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 bindings in a 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); } } }
mrydengren Feb 07 '10 at 13:21 2010-02-07 13:21
source share