Generics 如何使用Ninject检索通用接口的所有绑定

Generics 如何使用Ninject检索通用接口的所有绑定,generics,dependency-injection,ninject,ninject-2,ninject-extensions,Generics,Dependency Injection,Ninject,Ninject 2,Ninject Extensions,使用Ninject 2.2,我有以下失败测试(简化): 公共界面IGenericView { } 公共接口协议 { } 公共类DefaultConvention:IDefaultConvention { } 公共类DefaultConventionView:IGenericView { } 公共类StringView:IGenericView { } [测试夹具] 公共类考试 { 私有静态IKernel_内核; [设置] 公共作废设置() { _内核=新的标准内核(); } [测试] pu

使用Ninject 2.2,我有以下失败测试(简化):

公共界面IGenericView
{
}
公共接口协议
{
}
公共类DefaultConvention:IDefaultConvention
{
}
公共类DefaultConventionView:IGenericView
{ 
}
公共类StringView:IGenericView
{  
}
[测试夹具]
公共类考试
{
私有静态IKernel_内核;
[设置]
公共作废设置()
{
_内核=新的标准内核();
}
[测试]
public void可以解析AllClasseSClosingPengeneriInterface()
{
//安排
_kernel.Bind().To();
_内核扫描(
x=>
{
x、 从调用Assembly();
x、 BindWith(新的GenericBindingGenerator(typeof(IGenericView));
});
//表演
对象target1=_kernel.Get();
对象target2=_kernel.Get();
//断言
Assert.IsAssignableFrom(target1);
Assert.IsAssignableFrom(target2);
Assert.AreEqual(2,_kernel.GetAll(typeof(IGenericView)).Count();//始终返回0
}
}

前两个断言通过了,因此我知道类型本身被正确绑定,但我无法像我希望的那样检索开放泛型接口的所有绑定。这可能吗?

不可能。Ninject应该从哪里知道哪些类型可以作为泛型参数?以你的假设为例,为什么你认为2是正确的值?为什么不应该也返回
IGenericView
?此外,返回类型应该是什么<代码>IEnumerable不是允许的运行时类型<代码>IEnumerable可能不是人们所期望的


GetAll为请求类型的每个绑定返回一个实例,在本例中只有一个实例。在这种情况下,您必须定义一个通用的非泛型基接口,并为每种类型注册它,并为此接口调用GetAll。

否,这是不可能的。Ninject应该从哪里知道哪些类型可以作为泛型参数?以你的假设为例,为什么你认为2是正确的值?为什么不应该也返回
IGenericView
?此外,返回类型应该是什么<代码>IEnumerable不是允许的运行时类型<代码>IEnumerable可能不是人们所期望的


GetAll为请求类型的每个绑定返回一个实例,在本例中只有一个实例。在这种情况下,您必须定义一个通用的非通用基本接口,并为每种类型注册它,然后为此接口调用GetAll。

谢谢您的回答,Remo-我理解您的观点。一开始似乎不太正确,但我尝试该路由的唯一原因是GetAll不适用于继承的接口。如果我定义了
接口IGenericView:IView
,那么即使我指定了
类StringView:GenericView,IView
,我也不能调用
GetAll()
。这是我遇到的一个基本问题,我实际上希望能够获取由前面的Scan方法调用创建的所有绑定。是否有可能实现这一点?必须为所有类定义IView的绑定。由于您使用的是约定,因此可以轻松地执行此操作,例如使用RegexBindingGenerator或您自己的生成器。非常感谢您的帮助,Remo。最后,我决定走一条非常规路线,因为这给我带来了太多的麻烦,但你的回答肯定为我指明了正确的方向,让我克服了眼前的障碍。谢谢你的回答,雷莫-我理解你的观点。一开始似乎不太正确,但我尝试该路由的唯一原因是GetAll不适用于继承的接口。如果我定义了
接口IGenericView:IView
,那么即使我指定了
类StringView:GenericView,IView
,我也不能调用
GetAll()
。这是我遇到的一个基本问题,我实际上希望能够获取由前面的Scan方法调用创建的所有绑定。是否有可能实现这一点?必须为所有类定义IView的绑定。由于您使用的是约定,因此可以轻松地执行此操作,例如使用RegexBindingGenerator或您自己的生成器。非常感谢您的帮助,Remo。最后,我决定走一条非常规路线,因为这给我带来了太多的麻烦,但你的回答肯定为我指明了正确的方向,让我克服了眼前的障碍。
public interface IGenericView<T>
{
}

public interface IDefaultConvention
{
}

public class DefaultConvention : IDefaultConvention
{
}

public class DefaultConventionView : IGenericView<IDefaultConvention>
{ 
}

public class StringView : IGenericView<string>
{  
}

[TestFixture]
public class NinjectTests
{
    private static IKernel _kernel;

    [SetUp]
    public void Setup()
    {
        _kernel = new StandardKernel();
    }

    [Test]
    public void CanResolveAllClassesClosingOpenGenericInterface()
    {
        // Arrange
        _kernel.Bind<IDefaultConvention>().To<DefaultConvention>();
        _kernel.Scan(
            x =>
            {
                x.FromCallingAssembly();
                x.BindWith(new GenericBindingGenerator(typeof(IGenericView<>)));
            });

        // Act
        object target1 = _kernel.Get<IGenericView<IDefaultConvention>>();
        object target2 = _kernel.Get<IGenericView<string>>();

        // Assert
        Assert.IsAssignableFrom<DefaultConventionView>(target1);
        Assert.IsAssignableFrom<StringView>(target2);
        Assert.AreEqual(2, _kernel.GetAll(typeof(IGenericView<>)).Count()); // Always returns 0
    }
}