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