2

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

预期:与 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]);
}

但是当我尝试将两个绑定放在不同的模块中时,这将无济于事。或者这是一个坏主意吗?

4

1 回答 1

1

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

你应该做什么:

  1. 使用接口而不是BaseClass
  2. 找到一个编码约定来定义什么类型的类是单例。例如特殊命名,如以 Service 结尾
  3. 使用 BindAllInterfaces 绑定它们

当使用约定时,这不应该从消费者的角度来做,而应该从服务提供者的角度来做。所以不需要在不同的模块中对不同的接口类型进行绑定。

于 2013-02-20T12:01:08.860 回答