2011-10-19 30 views
9

bir kurucuya IEnumerable enjekte etmek Ben IEnumerable Ninject ile bir yapıcıya enjekte çalışıyorum.Bir Ninject fabrika yöntemiyle

Benim yapıcı şöyle görünür:

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

Benim Ninject modülü şuna benzer:

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 
    } 
} 

Bu çalışıyor gibi görünmüyor. Hiç bir hata alamıyorum. Ninject, yalnızca bağlamayı kullanmaz ve yapıcıya iletilen değer temelde yalnızca boş bir varsayılan değerdir.

Ninject ile bir IEnumerable nasıl enjekte edersiniz?

Düzenleme benim fabrika yöntemine

Daha fazla bilgi:

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..... 
    }; 
} 

Düzenleme 2

Remo'nun cevap dayanarak, olası bir çözüm bağlamak için bir foreach döngüsü kullanmaktır modelleri her seferinde bir kerede görüntüleyin:

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

Ben ToMethod' bu şekilde çalışır 'emin toplama desteği değilim ya: Remo'nun cevap dayanarak –

+0

@Merlyn, bu iyi bir nokta ... sadece "bir seviye yukarı git" ve tüm MatrixViewModel'i bağla (gerçek görünüm modelimin bir kaç parametresi var, bu yüzden her şeyi bağlamak için biraz daha çalışır). Neden benim çözüm bir cevap vermedi gelince, ben senin yorum hakkında aynı şeyi sorabilirim :) – devuxer

+0

Doğru :) Bu kesinlikle geçerli birden fazla geçerli çözümler var ... –

cevap

5

, olası bir çözüm her seferinde görünüm modellerini birini bağlamak için bir foreach döngü kullanmaktır. Bu olsa da işe yarayacak: Bind () ToMethod (context => yeni MatrixViewModel (GetFooViewModels())) `. Ayrıca, kendi cevabınızı sorunuza ekleyebilir ve Remo cevap olarak kabul etmek istediğiniz seviyeye gelmediyse kabul edebilirsiniz.
+0

Bu, bağlamaların oluşturulduğu anda ve özgün bağda ilk defa çözüldüğünde çağrılan GetFooViewModels() öğesinin çağrılması dışında, özgün bağlama ile aynı şeyi yapmalıdır. –

+0

Remo, orijinal bağımdaki diğer fark bu aslında çalışıyor :) Ama takip için teşekkür ederim. – devuxer

+0

@Remo: NInject özel kasalı koleksiyonların olduğu izlenimini aldım, bu nedenle koleksiyondaki türdeki tüm bağları çözer. Ve eğer özel durumlar varsa, diğer yolu çözmediyse şaşırmam. OP'deki davranış benim varsayımla uyuşuyor gibi görünüyor. https://github.com/ninject/ninject/wiki/Multi-injection –

14

Numaralandırıcılar, Ninject tarafından farklı şekilde ele alınır. Sadece tüm görünüm modelleri için bağlayıcılar sağlayın. Numaralandırılacaklar için: Ninject, her bir ciltleme uygulamasının bir örneğini oluşturacak ve bunları IEnumerable olarak geçirecektir.

örn. Sorunuzun itibaren

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

Remo, cevabınız için teşekkürler, ama Benim durumumu gerçekten ele almıyor.Fabrika yöntemim FooViewModel'den bir grup nesne değil, FooViewModel'den gelen bir grup nesne döndürmez. – devuxer

+0

Lütfen düzenlememe bakın. – devuxer

+0

Şu anda IEnumerable, IList, List ve diziler için bağları kullanamazsınız, çünkü bunlar özel olarak işlenir. Ne yazık ki, bir ICollection kullanarak ya da IEnumerable

3

:

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

Emin toplama desteği değilim ya ToMethod bu şekilde çalışır.

Bu olsa çalışacak olmalıdır:

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

, ne kadar yararlı bu çözüm size görünümler yapıyolar bağlıdır.

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

Görünüm modelinize enjekte edersiniz, bu durum durumunuza uygulanmaz. Ancak WPF/MVVM kullanıyorsanız ve görünüm modelini görünüme enjekte etmeye çalışıyorsanız, görünümümdeki herhangi bir kavram modelini kaldırmayı ve yalnızca görünümün 'DataContext'i 'ToMethod' olarak ayarlamayı seviyorum. –

+0

+1. İyi cevap ... Aslında bununla gidebilirim. – devuxer