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

发布于 2024-12-14 17:12:04 字数 1395 浏览 3 评论 0 原文

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

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

前两个断言通过,所以我知道类型本身已正确绑定,但我无法像我想要的那样检索开放通用接口的所有绑定。这有可能吗?

Using Ninject 2.2, I have the following failing test (simplified):

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

The first two assertions pass, so I know the types themselves are being bound correctly, but I can't retrieve all the bindings for the open generic interface like I want to. Is this at all possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最终幸福 2024-12-21 17:12:08

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

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

No that is not possible. Where should Ninject know from which types are allowed as generic parameters? Taking your assumption why do you think 2 is the correct value? Why shouldn't IGenericView<int> be returned too? Furthermore, what should be the return type? IEnumerable<IGenericView<>> isn't an allowed runtime type. IEnumerable<IGenericView<object>> probably isn 't what one expects.

GetAll returnes one instance for each binding of the requested type and there is exactly one in this case. You must define a common non generic base interface in this case and register it for each type and call GetAll for this interface.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文