2012-02-10 4 views
1

これは私の問題です。私はプレゼンタークラスを持っていて、IDataSourceをコンストラクター引数として取る 'Presenter'と呼ぶことができます。 IDataSourceインターフェイスにはさまざまな実装があります。いくつかの引数をNinjectに渡して、その引数に基づいていくつかのIDataSource実装の1つを使用する必要があります。私はいくつかのサンプルコードを以下に提供しました。私のソリューションは実際には醜いと思うし、これを行うにはもっとスマートでクリーンな方法が必要だと思う。あなたはどうやってこのタイプの問題を解決していますか?ここで引数を持つ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

ですこれは、あなたが何をしたいかに依存します。私はあなたが生産のためにテストのために別のdbを使いたいと思っています。この場合、心の中で生産構成でモジュールを作成し、単にテストのためにすべてを再バインドします:

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

+0

設定を念頭において、私はIDataSourceに対して2つの条件付きバインディングを使用します。 1つは.When(_ => Configuration.IsInMemory)、もう1つは.When(_ => Configuration.IsDb) –

+0

私は構築し、メイン画面のユーザーの選択に基づいて完全なビューをロードしようとしています。私は選択を追跡し、それを条件付きバインディングで使用するいくつかのクラスを導入することができたと思います。再度、感謝します! – Pelle

関連する問題