2012-03-07 21 views
5

Với giao diện sau:Tiêm một Enumerable chứa tất cả Triển khai đăng ký của một Interface

public interface IMyProcessor 
{ 
    void Process(); 
} 

Tôi muốn để có thể đăng ký nhiều triển khai và có chứa DI tôi tiêm một đếm được của họ vào một lớp học như này:

public class MyProcessorLibrary 
{ 
    private readonly IMyProcessor[] _processors; 

    public MyProcessingThing(IMyProcessor[] processors) 
    { 
     this._processors = processors; 
    } 

    public void ProcessAll() 
    { 
     foreach (var processor in this._processors) 
     { 
      processor.Process(); 
     } 
    } 
} 

Điều này có thể? Việc triển khai hiện tại của tôi là MyProcessorLibrary tra cứu tất cả các triển khai IMyProcessor tĩnh, nhưng tôi muốn thực hiện nó thông qua một vùng chứa nếu có thể. Tôi đang sử dụng Unity, nhưng tôi tò mò nếu các container khác hỗ trợ nó.

Edit:

Cảm ơn câu trả lời cho đến nay; rõ ràng là tôi muốn tiêm MyProcessorLibrary vào một lớp khác, và để nó được xây dựng như một phần của việc nối dây lên cây của các đối tượng phụ thuộc, ví dụ:

public class MyProcessorRepository 
{ 
    public MyProcessorRepository(MyProcessorLibrary processorLibrary) 
    { 
    } 
} 

public class MyProcessorService 
{ 
    public MyProcessorService(MyProcessorRepository processorRepository) 
    { 
    } 
} 

var container = new UnityContainer(); 
// Register a bunch of IMyProcessors... 

var service = container.Resolve<MyProcessorService>(); 
+1

thể trùng lặp của [Giải quyết IEnumerable với Unity] (http: // stackoverflow.com/questions/1961549/resolving-ienumerablet-with-unity) –

Trả lời

1

tôi không thể nói cho Unity như tôi không sử dụng nó, nhưng nó chắc chắn là có thể với Ninject (xem Multi Injection) mà tôi sử dụng.

+0

Tuyệt vời, đó là thực sự chính xác những gì tôi muốn làm ... nếu không có gì cho Unity tôi sẽ chấp nhận câu trả lời này một chút. Cảm ơn! :) –

4

Có, bạn có thể thực hiện việc này. Tất cả những gì bạn cần, là cung cấp cho tên chuỗi cho các loại bạn đang đăng ký với giao diện. Register không có tên chuỗi vẫn gán tên (theo như tôi nhớ là "Mặc định") nội bộ, nó được giải quyết khi bạn gọi Resolve<T>, nhưng nó không được giải quyết khi bạn gọi ResolveAll<T>. Vì vậy, bạn có thể cần phải cung cấp cho tất cả các bộ xử lý của bạn một số tên.

Một mẫu từ msdn (thích nghi):

// Create container and register types using a name for each one 
IUnityContainer myContainer = new UnityContainer(); 
myContainer.RegisterType<IMyProcessor, MyProcessorA>(); //default 
myContainer.RegisterType<IMyProcessor, MyProcessorB>("MyProcessorB"); 
myContainer.RegisterType<IMyProcessor, MyProcessorC>("MyProcessorC"); 

// Retrieve a list of non-default types registered for IMyProcessor 
// List will only contain the types MyProcessorB and MyProcessorC 
IEnumerable<IMyProcessor> serviceList = myContainer.ResolveAll<IMyProcessor>(); 

//usage 
var library = new MyProcessorLibrary(serviceList); 
library.ProcessAll(); 
+0

Cảm ơn rất nhiều vì điều này - Tôi không nghĩ tôi khá rõ ràng trong câu hỏi của mình. Tôi đã cập nhật nó. –

1

Đây là từ tài liệu Microsoft Unity 2.0. Kiểm tra phiên bản bạn sử dụng. Không chắc chắn cho những người khác IoC.

// Create container and register types using a name for each one 
IUnityContainer myContainer = new UnityContainer(); 
myContainer.RegisterType<IMyProcessor, MyProcessor1>(); 
myContainer.RegisterType<IMyProcessor, MyProcessor2>("number2"); 

// Retrieve a list of non-default types registered for IMyService 
IEnumerable<IMyProcessor> processors = myContainer.ResolveAll<IMyService>(); 

EDIT:

// update MyProcessorLibrary with this property 
[Dependency] 
public IEnumerable<IMyProcessor> MyProcessingThing 
{ 
get { return _processors; } 
set { _processors = value; } 
} 

//then inject the library class like this 
var lib = myContainer.Resolve<MyProcessorLibrary>(); 
myProcessorRepository(lib) 
+0

Cảm ơn rất nhiều vì điều này - tôi không nghĩ mình đủ rõ ràng trong câu hỏi của mình. Tôi đã cập nhật nó. –

0

Nó được hỗ trợ đầy đủ với MEF.

Bạn sẽ phải xuất khẩu tất cả các lớp học mà thực hiện giao diện này, sau đó sử dụng [ImportMany]

Ví dụ:

public interface IMyProcessor { void Process(); } 

[Export(typeof(IMyProcessor)] 
public class FirstProc : IMyProcessor { ... } 

[Export(typeof(IMyProcessor)] 
public class SecondProc : IMyProcessor { ... } 

[Export] 
public class MyTest() 
{ 
    [ImportMany] 
    public IMyProcessor[] MyProcessors { get; set; } 
} 
Các vấn đề liên quan