I Have three generic interfaces
public interface IRepositorioBase<T> where T : class { }
public interface IServiceBase<T> where T : class {}
public interface IAppBase<T> where T : class {}
for which I have three corresponding concrete generic class implementations
public class RepositorioBase<T> where T : class { }
public class ServiceBase<T> where T : class {}
public class AppBase<T> where T : class {}
and the other class are create using the class generics, example
public class ExpenseCardRepository : RepositoryBase<ExpenseCard>, IExpenseCardRepository{ }
public class ExpenseCardService : ServiceBase<ExpenseCard>, IExpenseCardService
{
private readonly IExpenseCardRepository _repository;
public ExpenseCardService(IExpenseCardRepository repository) : base(repository)
{
_repository = repository;
}
}
public class ExpenseCardApp : AppBase<ExpenseCard>, IExpenseCardApp
{
private readonly IExpenseCardService _service;
public ExpenseCardApp(IExpenseCardService service) : base(service)
{
_service = service;
}
}
I would like a generic code only to bind all types of interfaces depending on the type of class it inherits
These is example Ninject-Generic-Interface but I would like get of subclass.
What you're trying to achieve can only be done by creating an explicit binding for each type. After all IExpenseCardRepository : IRepositoryBase<ExpenseCard>
is different from ICustomerRepository : IRepositoryBase<Customer>
. Now the good news is that you can automate this kind of work, by using Ninject.Extension.Convention . If you stick to a naming convention, it can be done very easy. The naming convention is: Class name ends with the interface name (without a leading I of course). From your code it looks like you do. Then the solution is as easy as:
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom(typeof(IServiceBase<>))
.BindDefaultInterfaces());
This will bind ExpenseCardService
to IExpenseCardService
and IServiceBase<ExpenseCard>
.
If you don't adhere to this naming convention, then things get a little more complicated: you'll have to provide (customize) the binding creation part yourself. What you would have to do is implement an IBindingGenerator
and use the .BindWith<MyBindingGenerator>()
extension:
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom(typeof(IRepositorioBase<>))
.BindWith<MyBindingGenerator>());
Your binding generator would then have to decide which types to bind to and create and return those bindings.
I have to give a word of caution, though: in most cases when i've seen this kind of design it was not necessary (there was a simpler solution available). In general you should favor composition over inheritance .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.