为具有 NInject 的通用接口注册通用 类

Registering generic classes for generic interfaces with NInject

我有三个通用接口

public interface IRepositorioBase<T> where T : class {    }
public interface IServiceBase<T> where T : class {}
public interface IAppBase<T> where T : class {}

为此我有三个相应的具体通用 class 实现

public class RepositorioBase<T> where T : class {    }
public class ServiceBase<T> where T : class {}
public class AppBase<T> where T : class {}

和其他 class 是使用 class 泛型创建的,例如

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;
    }
}

我想要一个通用代码只绑定所有类型的接口 取决于它继承

的class的类型

这些是例子 Ninject-Generic-Interface 但我想得到 subclass.

您要实现的目标只能通过为每种类型创建显式绑定来完成。毕竟 IExpenseCardRepository : IRepositoryBase<ExpenseCard> 不同于 ICustomerRepository : IRepositoryBase<Customer>。 现在好消息是,您可以使用 Ninject.Extension.Convention 自动执行此类工作。如果你坚持一个命名约定,它可以很容易地完成。命名约定是:Class 名称以接口名称结尾(当然没有前导 I)。从您的代码看来,您确实这样做了。那么解决方案就这么简单:

kernel.Bind(x => x.FromThisAssembly()
    .SelectAllClasses()
    .InheritedFrom(typeof(IServiceBase<>))
    .BindDefaultInterfaces());

这会将 ExpenseCardService 绑定到 IExpenseCardServiceIServiceBase<ExpenseCard>


如果您不遵守此命名约定,那么事情会变得 一点点 更复杂:您必须自己提供(自定义)绑定创建部分。您需要做的是实施 IBindingGenerator 并使用 .BindWith<MyBindingGenerator>() 扩展名:

kernel.Bind(x => x.FromThisAssembly()
                  .SelectAllClasses()
                  .InheritedFrom(typeof(IRepositorioBase<>))
                  .BindWith<MyBindingGenerator>());

然后您的绑定生成器必须决定将哪些类型绑定 并创建和 return 这些绑定。


不过,我必须提醒一句:在大多数情况下,当我看到这种设计时,它是没有必要的(有一个更简单的解决方案可用)。 一般来说,你应该 favor composition over inheritance.