MEF: eksport, część II

W ostatnim poście przedstawiłem MEF wraz z prostym przykładem. Dzisiaj przyjrzymy się dokładniej sposobom eksportu. Znamy już podstawowy sposób eksportu klasy:

[Export(typeof(IMessageBoxService))]
public class WpfMessageBoxService:IMessageBoxService
{
}

Oprócz przekazania typu, można także użyć zwykłego string’a. Ze względu jednak na łatwość popełnienia literówki lepszym sposobem jest użycie typeof. Oprócz klas można również eksportować właściwości np.:

public class Order
{
   [Export("OrderValue")]
   public int Value { get { return 3; } }
}
public class OrderInvoker
{
   [Import("OrderValue")]
   public int Value { get; set; }
}

Po imporcie, OrderInvoker.Value będzie miał wartość 3.Łatwo to przetestować używając poniższego kodu:

AssemblyCatalog catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
CompositionContainer compositionContainer = new CompositionContainer(catalog);

OrderInvoker orderInvoker=new OrderInvoker();

// wyświetli 0
MessageBox.Show(orderInvoker.Value.ToString());
compositionContainer.ComposeParts(orderInvoker);            
// wyświetli 3
MessageBox.Show(orderInvoker.Value.ToString())

Również metody można eksportować:

public class Order
{
   [Export("Submit")]
   public void Submit()
   {
       MessageBox.Show("Submit");
   }
}
public class OrderInvoker
{
   [Import("Submit")]
   public Action SubmitInvoker { get; set; }

   public void Submit()
   {
       SubmitInvoker();
   }
}

Test:


AssemblyCatalog catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
CompositionContainer compositionContainer = new CompositionContainer(catalog);

OrderInvoker orderInvoker=new OrderInvoker();            
compositionContainer.ComposeParts(orderInvoker);            

// wyswietli msg
orderInvoker.Submit();

Ostatnią kwestią jest atrybut InheritedExport. Dodany do klasy bazowej, powoduje, że wszelkie klasy dziedziczące zostaną automatycznie wyeksportowane. Wystarczy, że klasa bazowa jest oznaczona InheritedExport:

[InheritedExport]
interface IAnyInterface
{
}
// Nie musimy już używać atrybutu Export, 
// ponieważ bazowy interfejs został oznaczony
// InheritedExport
public class AnyClass:IAnyInterface
{
}

Leave a Reply

Your email address will not be published.