[英]Registering generic classes for generic interfaces with NInject
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. 这些是示例Ninject-Generic-Interface,但我想获取子类。
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>
. 毕竟
IExpenseCardRepository : IRepositoryBase<ExpenseCard>
与ICustomerRepository : IRepositoryBase<Customer>
。 Now the good news is that you can automate this kind of work, by using Ninject.Extension.Convention . 现在,好消息是您可以使用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).
命名约定为:类名以接口名结尾(当然,不带前导I)。 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>
. 这会将
ExpenseCardService
绑定到IExpenseCardService
和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: 您要做的是实现
IBindingGenerator
并使用.BindWith<MyBindingGenerator>()
扩展名:
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 .
通常,您应该更喜欢使用组合而不是继承 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.