2011-10-19 36 views
9

我试图用Ninject将IEnumerable注入到构造函数中。使用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不会使用绑定,并且传递给构造函数的值基本上只是一个空的默认值。

如何为Ninject注入IEnumerable

编辑

更多关于我的工厂方法细节:

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循环绑定一次查看一个模型:

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

我不知道收集支持或'ToMethod'这样工作。这应该可以工作:'绑定()。ToMethod(context => new MatrixViewModel(GetFooViewModels()))''。此外,您可以将自己的答案添加到您的问题,并接受它,如果雷莫的不是你想接受的水平,作为答案。 –

+0

@Merlyn,这是一个很好的观点......只是“走上一个关卡”并绑定整个MatrixViewModel(我的真实视图模型有一些参数,所以绑定整个东西会有点麻烦)。至于为什么我没有把我的解决方案放入答案,我可以问你同样的事情关于你的评论:) – devuxer

+0

真:)肯定有多种有效的解决方案... –

回答

5

基于圣雷莫的回答,一个可能的解决方案是使用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

雷莫,谢谢你的回答,但它并没有真正解决我的情况。我的工厂方法返回一堆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,并试图将视图模型注入到视图中,我喜欢从视图中删除任何视图模型的概念,并在'ToMethod'中设置视图的'DataContext'。 –

+0

+1。很好的答案......我可能真的会这样做。 – devuxer

相关问题