2013-02-19 38 views
1

結合我得到了以下測試用例與失敗:Ninject.Extensions.Conventions進樣單身人士在列表上的接口和BaseClass的

預期:同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

範圍是爲綁定定義的。兩個綁定無法共享範圍。

你應該做的:

  1. 使用的界面,而不是BaseClass
  2. 鰭是一種編碼規範來定義什麼類型calsses是singeltons。例如特殊的命名就像使用BindAllInterfaces

當使用慣例,這不應該從消費者的角度來看,但是從服務提供商角度做過服務

  • Bindind他們的結局。所以不需要在不同的模塊中爲不同的接口類型綁定。

  • +0

    我不喜歡提取BaseClass接口來讓DI工作。所以即使使用Interface和BaseClass,我的發佈解決方案也可以工作。我只需要重新思考我的模塊。實際上,我的BaseClass是「BaseSpellInfo」,接口是「ILearnable」。所以有一個學習系統(模塊)可以處理所有可以學習的東西(不僅是法術),還有SpellInfos描述法術,應該是單身。如果我在兩個模塊中定義它們,我總是會獲得每個SpellInfo的兩個實例,在學習的上下文中以及在施放咒語的上下文中的一個。 – Tarion 2013-02-20 14:30:16