How to use the Ninject convention library to bind to a base type that is not an interface?

I am trying to search for a set of components that implement a specific base class in assemblies in the same directory as my application. I need to do this as a kind of plugin architecture, since my application uses these types to populate other components.

Ninject.Extensions.Conventions supports checking assemblies in a local directory, so I decided to take a snapshot.

The problem is that the binding generators that the library provides ( DefaultBindingGenerator and RegexBindingGenerator ) will only bind components to the interfaces that they implement. They will not bind to base types without an interface.

How to use this library to bind by agreement to the base class, and not to the interface?

I am using the version currently on NuGet - 2.2.0.5

My current conditional expression-based binding code is as follows:

 Kernel.Scan(x => { x.FromAssembliesMatching("*.dll"); x.WhereTypeInheritsFrom<BaseType>(); // I've tried both DefaultBindingGenerator and RegexBindingGenerator x.BindWith<DefaultBindingGenerator>(); x.InTransientScope(); }); 

When I try to resolve components, nothing is returned:

 var myTypes = Kernel.GetAll<BaseType>(); int count = myTypes.Count(); // Always returns zero 
+4
source share
2 answers

In the current code base on GitHub , you can use BaseBindingGenerator .

In the code base I have (currently on NuGet - 2.2.0.5), I solved this with a custom IBindingGenerator . It was pretty easy to write as soon as I looked at the sources for existing binding generators .

 public class BaseTypeBindingGenerator<TBase> : IBindingGenerator { private static readonly Type baseType = typeof(TBase); public void Process( Type type, Func<IContext, object> scopeCallback, IKernel kernel ) { if ( type.IsInterface || type.IsAbstract || type.BaseType != baseType) { return; } kernel.Bind(baseType).To(type).InScope(scopeCallback); } } 

I used it as follows:

 Kernel.Scan(x => { x.FromAssembliesMatching("*.dll"); x.WhereTypeInheritsFrom<BaseType>(); x.BindWith<BaseTypeBindingGenerator<BaseType>>(); x.InTransientScope(); }); // ... var myTypes = Kernel.GetAll<BaseType>(); int count = myTypes.Count(); // Didn't return zero! 
+6
source

Just updating Merlyn's answer, I am using ninject extensions conventions 3.2 and the signature has changed a bit ...

 public class BaseTypeBindingGenerator<TBase> : IBindingGenerator { private static readonly Type baseType = typeof (TBase); public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot) { if (type.IsInterface || type.IsAbstract || type.BaseType != baseType) { return Enumerable.Empty<IBindingWhenInNamedWithOrOnSyntax<object>>(); } return new [] { bindingRoot.Bind(baseType).To(type) }; } } 
0
source

Source: https://habr.com/ru/post/1386238/


All Articles