2011-10-19 22 views
9

Tôi đang cố gắng tiêm một IEnumerable vào một hàm tạo với Ninject.Tiêm một IEnumerable vào một hàm tạo với phương thức nhà máy Ninject

constructor của tôi trông như thế này:

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

My Ninject mô-đun trông như thế này:

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

này dường như không có tác dụng. Tôi không nhận được bất kỳ lỗi nào. Ninject không bao giờ sử dụng ràng buộc, và giá trị được truyền vào constructor về cơ bản chỉ là một giá trị mặc định rỗng.

Làm cách nào để bạn tiêm IEnumerable với Ninject?

Sửa

tin chi tiết về phương pháp nhà máy của tôi:

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

Chỉnh sửa 2

Dựa trên câu trả lời Remo, người ta giải pháp khả thi là sử dụng một vòng lặp foreach để ràng buộc xem từng mô hình một:

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

Tôi không phải là hỗ trợ bộ sưu tập chắc chắn hoặc 'ToMethod' hoạt động theo cách đó. Điều này sẽ làm việc mặc dù: 'Bind (). ToMethod (context => new MatrixViewModel (GetFooViewModels()))'. Ngoài ra, bạn có thể thêm câu trả lời của riêng mình cho câu hỏi của mình và chấp nhận câu hỏi đó nếu Remo không hoàn toàn đạt đến cấp độ bạn muốn chấp nhận làm câu trả lời. –

+0

@ Merlyn, đó là một điểm tốt ... chỉ cần "đi lên một cấp" và ràng buộc toàn bộ MatrixViewModel (mô hình xem thực của tôi có một vài thông số mặc dù, do đó, nó sẽ là một chút công việc để ràng buộc toàn bộ điều). Đối với lý do tại sao tôi đã không đưa giải pháp của tôi vào một câu trả lời, tôi có thể hỏi bạn cùng một điều về bình luận của bạn :) – devuxer

+0

Đúng :) Có chắc chắn nhiều giải pháp hợp lệ để ... –

Trả lời

5

Dựa trên câu trả lời Remo, người ta giải pháp khả thi là sử dụng một vòng lặp foreach để ràng buộc các mô hình xem cùng một lúc:

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

Điều này nên làm tương tự như ràng buộc ban đầu ngoại trừ GetFooViewModels() được gọi vào thời điểm các ràng buộc được tạo ra và trong ràng buộc ban đầu nó được gọi khi nó được giải quyết lần đầu tiên. –

+0

Remo, sự khác biệt khác từ ràng buộc ban đầu của tôi là điều này thực sự hoạt động :) Nhưng cảm ơn bạn đã theo dõi. – devuxer

+0

@Remo: Tôi có ấn tượng rằng các bộ sưu tập đặc biệt của NInject, vì vậy nó sẽ giải quyết tất cả các ràng buộc của loại trong bộ sưu tập. Và nếu có trường hợp đặc biệt, tôi sẽ không ngạc nhiên nếu nó * không * giải quyết theo cách khác. Các hành vi trong OP dường như phù hợp với giả định của tôi. https://github.com/ninject/ninject/wiki/Multi-injection –

14

Số đếm được xử lý khác nhau bởi Ninject. Chỉ cung cấp các ràng buộc cho tất cả các kiểu xem. Đối với số liệu Ninject sẽ tạo ra một cá thể của mỗi ràng buộc áp dụng và chuyển chúng thành IEnumerable.

ví dụ:

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

Remo, cảm ơn câu trả lời của bạn, nhưng nó không thực sự giải quyết tình hình của tôi.Phương thức factory của tôi trả về một loạt các cá thể của FooViewModel, không phải là một loạt các đối tượng kế thừa từ FooViewModel. – devuxer

+0

Vui lòng xem chỉnh sửa của tôi. – devuxer

+0

Hiện tại bạn không thể sử dụng các ràng buộc cho IEnumerable, IList, List và mảng vì chúng được xử lý đặc biệt. Thật không may bạn phải workaraound một chút bằng cách sử dụng hoặc một ICollection hoặc bắt nguồn từ giao diện của riêng bạn từ IEnumerable

3

Từ câu hỏi của bạn:

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

Tôi không chắc chắn hỗ trợ bộ sưu tập hoặc ToMethod hoạt động theo cách đó.

này nên sẽ làm việc mặc dù:

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

Tất nhiên, làm thế nào hữu ích giải pháp này là phụ thuộc vào cách bạn đang xây dựng lên quan điểm của bạn.

+0

Bạn đang tiêm vào mô hình chế độ xem của mình, vì vậy, điều này không áp dụng cho trường hợp của bạn. Nhưng nếu bạn đang sử dụng WPF/MVVM, và cố gắng đưa mô hình khung nhìn vào khung nhìn, tôi muốn loại bỏ bất kỳ khái niệm nào của các mô hình khung nhìn từ chế độ xem của tôi và chỉ cần thiết lập 'DataContext' của khung nhìn trong' ToMethod'. –

+0

+1. Câu trả lời tốt ... Tôi thực sự có thể đi với điều này. – devuxer

Các vấn đề liên quan