NInject with a common interface

I defined one interface and one class:

public interface IRepository<T> { } public class RoleRepository:IRepository<Domain_RoleInfo> { } 

Entering here:

 public RoleService { [Inject] public RoleService(IRepository<Domain_RoleInfo> rep) { _roleRep=rep; } } 

How can I inject dependencies using Ninject, let's say how to link?

I wrote a helper class, as shown below, it works fine with a non-common interface. but how to reorganize it, it supports a common interface, as described above?

 public class RegisterNinjectModule : NinjectModule { public override void Load() { BindServices(); BindRepositories(); } private void BindServices() { FindAndBindInterfaces("RealMVC.Service.Interfaces", "RealMVC.Services"); } private void BindRepositories() { FindAndBindInterfaces("RealMVC.Repository.Interfaces", "RealMVC.Repositories"); } private void FindAndBindInterfaces(string interfaceAssemblyName, string implAssemblyName) { //Get all interfaces List<Type> interfaces = Assembly.Load(interfaceAssemblyName).GetTypes().AsQueryable().Where(x => x.IsInterface).ToList(); IQueryable<Type> ts = Assembly.Load(implAssemblyName).GetTypes().AsQueryable().Where(x => x.IsClass); foreach (Type intf in interfaces) { Type t = ts.Where(x => x.GetInterface(intf.Name) != null).FirstOrDefault(); if (t != null) { Bind(intf).To(t).InSingletonScope(); } } } } 
+41
generics c # ninject
Feb 07 '10 at 6:01
source share
4 answers

This should work: -

 Bind(typeof(IRepository<>)).To(typeof(Repository<>)); 

where: -

IRepository <> is the form interface: -

 public interface IRepository<T> where T : class { //... } 

Repository <> is a form class: -

 public class Repository<T> : IRepository<T> where T : class { //... } 

Hope this helps :-)

+78
Mar 11
source share

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(); } /// <summary> /// The concrete implementation. /// </summary> public Type Implementation { get; private set; } /// <summary> /// The interfaces implemented by the implementation. /// </summary> public IEnumerable<Type> Interfaces { get; private set; } /// <summary> /// Returns a value indicating whether the implementation /// implements the specified open generic type. /// </summary> public bool ImplementsOpenGenericTypeOf(Type openGenericType) { return Interfaces.Any(i => i.IsOpenGeneric(openGenericType)); } /// <summary> /// Returns the service type for the concrete implementation. /// </summary> public Type GetService(Type openGenericType) { return Interfaces.First(i => i.IsOpenGeneric(openGenericType)) .GetGenericArguments() .Select(arguments => openGenericType.MakeGenericType(arguments)) .First(); } } 

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); } } } 
+5
Feb 07 '10 at 13:21
source share

If you import a Ninject legend extension, its GenericBindingGenerator can help you. It adds support for common interfaces.

+2
Mar 03 '11 at 7:15
source share

Just a question in your FindAndBindInterfaces method: inside the foreach you have no problem closing in the intf variable? I'm still not sure I understand how the closure problem works.

In any case, to be safe, I think you should change your foreach to something like:

 foreach (Type intf in interfaces) { var tmp = intf; Type t = ts.Where(x => x.GetInterface(tmp.Name) != null).FirstOrDefault(); if (t != null) { Bind(intf).To(t).InSingletonScope(); } } 
0
May 29 '10 at
source share



All Articles