MEF: import, część III

W dzisiejszym poście kilka słów i imporcie implementacji. W poprzednich postach, pokazałem jak dokonywać prostych importów. Dzisiaj trochę więcej szczegółów. Dla przypomnienia, aby zaimportować (wstrzyknąć) implementację, w najprostszym przypadku używamy po prostu atrybutu Import:

public class SampleViewModel
{
    //...
    [Import]
    public IMessageBoxService MessageBoxService{get;set;}
}

Powyższy przykład reprezentuje wstrzyknięcie właściwości. W podobny sposób można wstrzykiwać parametry dla konstruktora:

public class SampleViewModel
{
    [ImportingConstructor]
    public SampleViewModel(IMessageBoxService service)
    {
        MessageBoxService = service;
    }
    public IMessageBoxService MessageBoxService{get;private set;}
}

Podczas importu SampleViewModel, automatycznie zostanie uruchomiony konstruktor importujący (IMessageBoxService również zostanie wstrzyknięty). Parametry wejściowe można oznaczyć atrybutem Import jeśli korzystamy z niestandardowego kontraktu.

Wcześniej nie zostało to pokazane, ale również zwykłe pola mogą zostać wstrzykiwane:

public class SampleViewModel
{
    //...
    [Import]
    private IMessageBoxService _messageBoxService;
}

Domyślnie, jeśli w kontenerze nie ma implementacji, import zakończy się wyjątkiem. Jeśli nasza architektura przewiduje, że kontener może być pusty wtedy możemy skorzystać z właściwości AllowDefault:

public class SampleViewModel
{
    //...
    [Import(AllowDefault=true)]
    public IMessageBoxService MessageBoxService{get;set;}
}

Jeśli  w kontenerze istnieje kilka implementacji, wtedy standardowy import zostanie również zakończony wyjątkiem – nie wiadomo której implementacji użyć. Możemy jednak zażądać wszystkich implementacji za pomocą atrybutu ImportMany:

public class SampleViewModel
{
    //...
    [ImportMany]
    public IMessageBoxService[] AllServices{get;set;}
}

Na zakończenie, warto wspomnieć o interfejsie  IPartImportsSatisfiedNotification, który posiada jedną metodę  OnImportsSatisfied, uruchamianą po imporcie wszystkich elementów danej klasy:

 public class SampleViewModel : IPartImportsSatisfiedNotification
 {
    // lista importowanych części

    public void OnImportsSatisfied() 
    {
      // wszytkie elementy zostały zaimportowane.
    } 
 }

Leave a Reply

Your email address will not be published.