【问题标题】:Ninject Bindings: same interface binded to different types. why works?Ninject Bindings:绑定到不同类型的相同接口。为什么有效?
【发布时间】:2013-01-16 11:42:17
【问题描述】:

我有三个项目

  • 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 如何知道如何区分它们?

【问题讨论】:

  • 您预计哪一行代码会失败?第二个绑定还是你尝试解析接口的那一行?
  • 接口不同..BDBADB ...
  • 将同一个接口绑定到另一种类型时的第二次绑定
  • 您的意思是存储库?从你的例子中取出上下文..这很令人困惑:(
  • 查看这篇文章,我认为这解释了它为什么/如何工作github.com/ninject/ninject/wiki/Multi-injection

标签: c# dependency-injection ninject


【解决方案1】:

将多个实现绑定到单个接口是绝对正确的。然后,您可以让 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=&gt; ItIsRightTimeToInjectAImplementation())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 2014-08-23
    • 1970-01-01
    相关资源
    最近更新 更多