2012-03-07 10 views
5

otrzymuje następujące interfejs:wstrzykiwanie przeliczalny zawierający wszystkie zarejestrowane implementacje w interfejs

public interface IMyProcessor 
{ 
    void Process(); 
} 

Chciałbym, aby móc zarejestrować wiele wdrożeń i mają mój DI kontener wstrzykiwania przeliczalny z nimi do klasy jak to:

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(); 
     } 
    } 
} 

Czy to możliwe? Moja obecna implementacja MyProcessorLibrary wyszukuje statycznie wszystkie implementacje IMyProcessor, ale wolałbym to zrobić przez kontener, jeśli mogę. Używam Unity, ale jestem ciekawy, czy wspierają go inne pojemniki.

Edit:

Dzięki za odpowiedzi tak daleko; dla jasności chcę wstrzyknąć MyProcessorLibrary do innej klasy i zbudować ją jako część okablowania drzewa obiektów zależnych, np.

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

możliwe duplikat [Rozwiązywania IEnumerable z Unity] (http: // stackoverflow.com/questions/1961549/resolving-ienumerablet-withunity) –

Odpowiedz

1

Nie mogę mówić za Jedności jak nie używam, ale to jest na pewno możliwe Ninject (patrz Multi Injection), które ja używam.

+0

Awesome, właściwie to właśnie chcę zrobić ... jeśli nic nie pojawi się w Unity, zaakceptuję tę odpowiedź nieco. Dzięki! :) –

4

Tak, można to zrobić. Wszystko, czego potrzebujesz, to podanie nazw łańcuchów dla typów rejestrowanych przez interfejs. Register bez nazwy strun nadal assignes nazwę (o ile pamiętam to „Default”) wewnętrznie, uchwala się, gdy nazywają Resolve<T>, ale nie zostanie rozwiązany po zadzwonić ResolveAll<T>. Być może będziesz musiał podać wszystkim swoim procesorom nazwy.

Próbka z msdn (dostosowany):

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

Bardzo dziękuję za to - nie sądzę, abym był wystarczająco jasny w moim pytaniu. Zaktualizowałem to. –

1

to od Microsoft Unity dokumentacji 2.0. Sprawdź wersję, której używasz. Nie jestem pewien dla innych 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

Dziękuję bardzo za to - nie sądzę, abym był wystarczająco jasny w moim pytaniu. Zaktualizowałem to. –

0

Jest w pełni obsługiwany przez MEF.

Trzeba by wyeksportować wszystkie klasy implementujące ten interfejs, a następnie użyj [ImportMany]

Przykład:

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; } 
} 
Powiązane problemy