2012-02-10 81 views
1

這是我的問題。我有一個演示者類,我們稱之爲'Presenter',它將IDataSource作爲構造函數參數。 IDataSource接口有不同的實現。我希望能夠將一些參數傳遞給Ninject,並根據該參數使用幾個IDataSource實現中的一個。我在下面提供了一些示例代碼。我認爲我的解決方案非常難看,而且必須有一個更智能,更清潔的方法來做到這一點。你們如何解決這類問題?Ninject帶參數的召喚圖

這裏是我的示例代碼

public class Presenter 
{ 
    public Presenter(IDataSource dataSource) 
    { 
     DataSource = dataSource; 
    } 

    private IDataSource DataSource { get; set; } 

    public List<string> GetData() 
    { 
     return DataSource.GetAll(); 
    } 
} 

public class InMemoryDataSource : IDataSource 
{ 
    public List<string> GetAll() 
    { 
     return new List<string> {"a", "b"}; 
    } 
} 

public class DbDataSource : IDataSource 
{ 
    public List<string> GetAll() 
    { 
     return new List<string> { "1", "2" }; 
    } 
} 

public interface IDataSource 
{ 
    List<string> GetAll(); 
} 

public class Module : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<Presenter>().To<Presenter>().Named("Db"); 
     Bind<Presenter>().To<Presenter>().Named("InMemory"); 
     Bind<IDataSource>().To<InMemoryDataSource> ().WhenParentNamed("InMemory"); 
     Bind<IDataSource>().To<DbDataSource>().WhenParentNamed("Db"); 
    } 
} 

[Test] 
public void Run() 
    { 
     using (var kernel = new StandardKernel(new Module())) 
     { 
      var p = kernel.Get<Presenter>(x => x.Name == "InMemory"); 

      foreach(var s in p.GetData()) 
      { 
       Console.Out.WriteLine(s); 
      } 
     } 
    } 

回答

2

這取決於你想要做什麼。我假設你想要使用不同的數據庫進行測試而不是生產。在這種情況下會創建模塊在頭腦裏的生產配置,只需重新綁定測試一切:

public class Presenter 
{ 
    public Presenter(IDataSource dataSource) 
    { 
     DataSource = dataSource; 
    } 

    private IDataSource DataSource { get; set; } 

    public List<string> GetData() 
    { 
     return DataSource.GetAll(); 
    } 
} 

public class InMemoryDataSource : IDataSource 
{ 
    public List<string> GetAll() 
    { 
     return new List<string> {"a", "b"}; 
    } 
} 

public class DbDataSource : IDataSource 
{ 
    public List<string> GetAll() 
    { 
     return new List<string> { "1", "2" }; 
    } 
} 

public interface IDataSource 
{ 
    List<string> GetAll(); 
} 

public class Module : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<Presenter>().To<Presenter>(); 
     Bind<IDataSource>().To<DbDataSource>(); 
    } 
} 

[Test] 
public void Run() 
    { 
     using (var kernel = new StandardKernel(new Module())) 
     { 
      kernel.Rebind<IDataSource>().To<InMemoryDataSource>(); 
      var p = kernel.Get<Presenter>(); 

      foreach(var s in p.GetData()) 
      { 
       Console.Out.WriteLine(s); 
      } 
     } 
    } 
+0

其實我有不同的數據源,用戶可以從中選擇,磁盤上的文件,數據庫等。該解決方案工程非常適合我的目的!非常感謝! – Pelle 2012-02-10 10:31:35

+0

考慮到配置,我會爲IDataSource使用兩個條件綁定。一個與.When(_ => Configuration.IsInMemory),另一個與.When(_ => Configuration.IsDb) – 2012-02-10 19:20:00

+0

我試圖建立並加載基於主屏幕上的用戶選擇的完整視圖。我想我可以介紹一些跟蹤選擇和使用條件綁定的類。再次感謝! – Pelle 2012-02-11 09:31:14