1

我有三个项目

  • 应用程序.基础设施
  • 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 如何知道如何区分它们?

4

1 回答 1

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 不会在绑定时检查依赖项是否可以解决,而是在应该发生注入时检查。

这完全有道理,因为某些类型的上下文绑定的条件可能会随着时间而改变(例如,如果您使用.When(x=> ItIsRightTimeToInjectAImplementation()).

于 2013-01-16T13:03:51.833 回答