Ninject.Extensions.Conferences在绑定接口和基类的列表中注入Singleton

本文关键字:列表 注入 Singleton 基类 Conferences Extensions 绑定 接口 Ninject | 更新日期: 2023-09-27 18:00:06

我得到了以下将失败的测试用例:

应为:与ArxScriptsTests.Engines.Ioc.Examples+A相同,但为:ArxScriptsTests.Engines.Ioc.Examples+A

问题是,如何把它做好?

[TestFixture]
public class Examples
{
    public interface IInterface
    {
    }
    public abstract class BaseClass : IInterface
    {
    }
    public class A : BaseClass
    {
    }
    public class B : BaseClass
    {
    }

    [Test]
    public void TestMethod1()
    {
        IKernel kernel = new StandardKernel();
        // Bind to self
        kernel.Bind(x => x
            .FromThisAssembly()
            .SelectAllClasses().InheritedFrom<BaseClass>()
            .BindToSelf()
            .Configure(b => b.InSingletonScope())
            );
        // Bind to IInterface
        kernel.Bind(x => x
            .FromThisAssembly()
            .SelectAllClasses().InheritedFrom<IInterface>()
            .BindSelection((type, baseTypes) => new List<Type> { typeof(IInterface) })
            .Configure(b => b.InSingletonScope())
            );

        // Bind to BaseClass
        kernel.Bind(x => x
            .FromThisAssembly()
            .SelectAllClasses().InheritedFrom<BaseClass>()
            .BindSelection((type, baseTypes) => new List<Type> { typeof(BaseClass) })
            .Configure(b => b.InSingletonScope())
            );


        List<IInterface> byInterface = new List<IInterface>(kernel.GetAll<IInterface>());
        List<BaseClass> byBaseClass = new List<BaseClass>(kernel.GetAll<BaseClass>());

        Assert.AreSame(byInterface[0], byBaseClass[0]);
    }
}

一种解决方案是

[Test]
public void TestMethod1()
{
    IKernel kernel = new StandardKernel();
    // Bind to Both
    kernel.Bind(x => x
        .FromThisAssembly()
        .SelectAllClasses().InheritedFrom<IInterface>()
        .BindSelection((type, baseTypes) => new List<Type> { typeof(IInterface), typeof(BaseClass) })
        .Configure(b => b.InSingletonScope())
        );

    List<IInterface> byInterface = new List<IInterface>(kernel.GetAll<IInterface>());
    List<BaseClass> byBaseClass = new List<BaseClass>(kernel.GetAll<BaseClass>());

    Assert.AreSame(byInterface[0], byBaseClass[0]);
}

但是当我尝试将两个绑定放在不同的模块中时,这将没有帮助。还是这是个坏主意?

Ninject.Extensions.Conferences在绑定接口和基类的列表中注入Singleton

范围是为绑定定义的。两个绑定不可能共享作用域。

你应该做什么:

  1. 使用接口而不是BaseClass
  2. Fins是一个编码约定,用于定义什么类型的caless是singelton。例如以服务结尾的特殊命名
  3. 使用BindAllInterfaces绑定它们

当使用约定时,这不应该从消费者的角度进行,而应该从服务提供商的角度进行。因此,不需要为不同模块中的不同接口类型绑定。