2011-10-19 7 views
9

IEnumerableをNinjectのコンストラクタに挿入しようとしています。Ninjectファクトリメソッドを持つコンストラクタにIEnumerableを注入

私のコンストラクタは次のようになります。

public MatrixViewModel(IEnumerable<FooViewModel> fooViewModels) 
{ 
    _fooViewModels = fooViewModels; 
} 

マイNinjectモジュールは次のようになります。

public class MainModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IEnumerable<FooViewModel>>() 
      .ToMethod(context => GetFooViewModels()) 
      .InSingletonScope(); // this binding is not working 
    } 

    private IEnumerable<FooViewModel> GetFooViewModels() 
    { 
     // returns a bunch of foo view models 
    } 
} 

これは動作していないようです。私は何の誤りもありません。 Ninjectはバインディングを使用することはなく、コンストラクタに渡される値は基本的に空のデフォルト値です。

IEnumerableにNinjectをどのように注入しますか?

編集は私のファクトリメソッドで

詳細:

private IEnumerable<FooViewModel> GetFooViewModels() 
{ 
    return new[] 
    { 
     new FooViewModel 
     { 
      Bar = new BarViewModel 
      { 
       X = 1, 
       Y = 2 
      }, 
      Misc = "Hello" 
     }, 
     new FooViewModel 
     { 
      Bar = new BarViewModel 
      { 
       X = 3, 
       Y = 4 
      }, 
      Misc = "Goodbye" 
     }, 
     // etc..... 
    }; 
} 

レモの答えに基づいて編集2

、一つの可能​​な解決策をバインドするために、foreachループを使用することです一度に1つのモデルを表示します。

foreach (var fooViewModel in GetFooViewModels()) 
{ 
    Bind<FooViewModel>().ToConstant(fooViewModel); 
} 
+1

私は確信して、コレクションのサポートはないですか 'ToMethod'がそのように動作します。 'Bind ()。ToMethod(context => new MatrixViewModel(GetFooViewModels()))'これはうまくいくはずです。また、自分の質問に自分の答えを追加して、レモが答えとして受け入れたいレベルにあまりない場合は、それを受け入れることができます。 –

+0

@Merlyn、それは良い点です...ただ "レベルアップ"してMatrixViewModel全体をバインドしてください(私の実際のビューモデルにはいくつかのパラメータがありますので、全体をバインドするにはもう少し作業が必要です)。私の解答を答えに入れなかった理由は、私はあなたのコメントについて同じことを尋ねることができました:) – devuxer

+0

真:これには確かに複数の有効な解決策があります... –

答えて

5

、一つの可能​​な解決策は、一度にビューモデル1をバインドするforeachループを使用することです:

foreach (var fooViewModel in GetFooViewModels()) 
{ 
    Bind<FooViewModel>().ToConstant(fooViewModel); 
} 
+0

これは、バインディングが作成されたときにGetFooViewModels()が呼び出され、最初に解決されたときに呼び出された元のバインディングで呼び出されるという点を除いて、元のバインディングと同じことを行う必要があります。 –

+0

レモ、私の元々の拘束とのもう一つの違いは、実際にはこれが働いていることです:)しかし、フォローアップに感謝します。 – devuxer

+0

@Remo:Ninjectの特殊ケースコレクションの印象を受けて、コレクションのすべてのバインディングを解決します。それが特別なケースであれば、それ以外の方法で解決しなければ驚くことはありません。 OPでの行動は私の前提に合っているようです。 https://github.com/ninject/ninject/wiki/Multi-injection –

14

列挙型は、Ninjectによって別々に扱われます。すべてのビューモデルにバインディングを提供するだけです。列挙型の場合、Ninjectはすべての適用バインディングのインスタンスを作成し、IEnumerableとして渡します。

あなたの質問から

Bind<FooViewModel>().To<FooViewModel1>(); 
Bind<FooViewModel>().To<FooViewModel2>(); 
+0

Remo、あなたの答えに感謝します。それは本当に私の状況に対処していません。私のファクトリメソッドは、FooViewModelから継承したオブジェクトの集合ではなく、FooViewModelのインスタンスの束を返します。 – devuxer

+0

私の編集をご覧ください。 – devuxer

+0

現在IEnumerable、IList、List、および配列は、特別に処理されるため、バインディングを使用することはできません。残念ながら、ICollectionを使用するか、IEnumerable

3

Bind<IEnumerable<FooViewModel>>() 
    .ToMethod(context => GetFooViewModels()) 

私は確信して、コレクションのサポートはないですかToMethodはそのように動作します。

しかしこれはうまくいくはずです。もちろん

Bind<MatrixViewModel>() 
    .ToMethod(context => new MatrixViewModel(GetFooViewModels())) 

を、あなたはあなたの意見を構築しているかに依存してどのように便利なこの解決策はあります。レモの答えに基づいて

+0

ビューモデルに注入しているので、これはあなたの状況には当てはまりません。しかし、WPF/MVVMを使用していて、ビューモデルをビューに挿入しようとすると、ビューからビューモデルのコンセプトを削除して、ビューの 'DataContext'を' ToMethod'に設定するのが好きです。 –

+0

+1。良い答え...私は実際にこれと一緒に行くかもしれません。 – devuxer

関連する問題