Ninject.Extensions.Conventions在Interface和BaseClass上的Lists绑定中注入单例

时间:2013-02-19 21:08:19

标签: c# binding singleton ninject

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

  

预期:与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]);
}
当我尝试将两个绑定放在不同的模块中时,

但是无济于事。或者这是个坏主意吗?

1 个答案:

答案 0 :(得分:1)

为绑定定义了范围。两个绑定无法共享范围。

你应该做什么:

  1. 使用界面代替BaseClass
  2. 完成编码约定以定义什么类型的calsses是singeltons。例如特殊命名,如以服务
  3. 结尾
  4. 使用BindAllInterfaces
  5. 绑定他们

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