Ninject Bindings:绑定到不同类型的相同接口。为何有效?

时间:2013-01-16 11:42:17

标签: c# dependency-injection ninject

我有三个项目

  • Application.Infrastructure
  • Application.A(引自Application.Infrastructure
  • Application.B(引自Application.Infrastructure
  • Application.Web(所有参考)

Application.Infrastructure我有一个通用的存储库类

public interface IRepository<T>
{
    T FirstOrDefault(Expression<Func<T, bool>> where);
}

Application.A我有这个存储库的实现

public class ApplicationARepository<T> : IRepository<T>
{
    private readonly IApplicationADBContext _context;
    public ApplicationARepository(IApplicationADBContext context)
    {
        _context = context;
    }
    // implementation
}

Application.B我有另一个存储库接口实现

public class ApplicationBRepository<T> : IRepository<T>
{
    private readonly IApplicationBDBContext _context;
    public ApplicationBRepository(IApplicationBDBContext context)
    {
        _context = context;
    }
    // implementation
}

在Application.Web中,我使用Ninject绑定接口

// Bind implementations from Application.A
kernel.Bind<IApplicationADBContext>().To<ApplicationADBContext>().InRequestScope();
kernel.Bind(typeof(IRepository<>)).To(typeof(ApplicationARepository<>));

// Bind implementations from Application.B
kernel.Bind<IApplicationBDBContext>().To<ApplicationBDBContext>().InRequestScope();

// Here should fail. I already binded typeof(IRepository<>) to typeof(ApplicationARepository<>)
kernel.Bind(typeof(IRepository<>)).To(typeof(ApplicationBRepository<>));

即使我将相同的接口绑定到两个不同的类型,而没有指定任何.Where()子句,它仍然有效,我没有任何错误。

为什么呢? Ninject如何知道如何区分它们?

1 个答案:

答案 0 :(得分:0)

将多个实现绑定到单个接口是绝对正确的。然后,您可以让Ninject将它们注入IEnumerable。您甚至可以多次绑定一个实现。

例如:

// binding
kernel.Bind<IService>().To<BasicService>();
kernel.Bind<IService>().To<BasicService>();

// injection
private IEnumerable<IService> myServices;

public NeedServices(IEnumerable<IService> myServices)
{
     this.myServices = myServices;
}

您将获得对BasicService的两个引用的集合。

如果您尝试注入单个实现,则会出现错误的情况。当Ninject尝试解决依赖关系时,错误将会出现(并且他不知道要选择哪个实现)。

public NeedService(IService myService)
{
     this.myService = myService;
}

因此,解决方案是Ninject不检查在绑定时是否可以解析依赖关系,但是在注入时应该解决。

这完全有道理,因为某些Contextual-Binding的条件可能会及时发生变化(例如,如果您使用.When(x=> ItIsRightTimeToInjectAImplementation())