I was looking for something related: I did not want to specify all the bindings separately, using the extension of the Convention.
First: You need to enter a List<IExtract> and inherit IExtract<T> : IExtract . This is because in C # you cannot specify the type of collection containing different generics. As you noted in your question, this is not valid syntax - for good reason other than this answer.
You can then infer elements from IExtract from the list and use reflection to get the type parameter and drop it. Or, if you know which extractor you are looking for:
public IExtract<T> GetExtractor<T>() { return (IExtract<T>)Extractors.Find(e => e is ExtractImpl<T>); }
Now you can have many classes for which you want some T to bind to IExtract`.
Bind<IExtract>().To<ExtractImpl<MyEntity>>(); Bind<IExtract>().To<ExtractImpl<YourEntity>>();
Where
MyEntity : BaseEntity YourEntity : BaseEntity
You can specify the Convention as follows
Kernel.Bind(x => x.FromThisAssembly().SelectAllClasses() .InheritedFrom<BaseEntity>() .BindWith(new GenericArgumentBindingGenerator(typeof(IExtract<>))));
Where the GenericArgumentBindingGenerator displayed as:
public class GenericArgumentBindingGenerator : IBindingGenerator { private readonly Type m_Generic; public GenericArgumentBindingGenerator(Type generic) { if (!generic.IsGenericTypeDefinition) { throw new ArgumentException("given type must be a generic type definition.", "generic"); } m_Generic = generic; } public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot) { if (type == null) throw new ArgumentNullException("type"); if (bindingRoot == null) throw new ArgumentNullException("bindingRoot"); if (type.IsAbstract || type.IsInterface) { return Enumerable.Empty<IBindingWhenInNamedWithOrOnSyntax<object>>(); } var bindings = new List<IBindingWhenInNamedWithOrOnSyntax<object>>(); IBindingWhenInNamedWithOrOnSyntax<object> binding = bindingRoot .Bind(typeof(IExtract))
Tarion
source share