Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieser Artikel enthält eine Übersicht über das managed Extensibility Framework, das in .NET Framework 4 eingeführt wurde.
Was ist MEF?
Das Managed Extensibility Framework (MEF) ist eine Bibliothek zum Erstellen einfacher und erweiterbarer Anwendungen. Es ermöglicht Anwendungsentwicklern, Erweiterungen ohne erforderliche Konfiguration zu ermitteln und zu verwenden. Außerdem können Erweiterungsentwickler Code einfach kapseln und fragile harte Abhängigkeiten vermeiden. MEF ermöglicht nicht nur die Wiederverwendung von Erweiterungen innerhalb von Anwendungen, sondern auch für alle Anwendungen.
Das Problem der Erweiterbarkeit
Stellen Sie sich vor, Sie sind der Architekt einer großen Anwendung, die Unterstützung für die Erweiterbarkeit bereitstellen muss. Ihre Anwendung muss eine potenziell große Anzahl kleinerer Komponenten enthalten und ist für die Erstellung und Ausführung verantwortlich.
Der einfachste Ansatz für das Problem besteht darin, die Komponenten als Quellcode in Ihre Anwendung einzuschließen und sie direkt aus Ihrem Code aufzurufen. Dies hat eine Reihe offensichtlicher Nachteile. Am wichtigsten ist, dass Sie keine neuen Komponenten hinzufügen können, ohne den Quellcode zu ändern, eine Einschränkung, die beispielsweise in einer Webanwendung akzeptabel sein kann, aber in einer Clientanwendung nicht funktioniert. Ebenso problematisch ist es, dass Sie keinen Zugriff auf den Quellcode für die Komponenten haben, da sie möglicherweise von Dritten entwickelt werden, und aus demselben Grund können Sie nicht zulassen, dass sie auf Ihre Komponenten zugreifen können.
Ein etwas komplexerer Ansatz wäre die Bereitstellung eines Erweiterungspunkts oder einer Schnittstelle, um die Entkopplung zwischen der Anwendung und den zugehörigen Komponenten zu ermöglichen. Unter diesem Modell können Sie eine Schnittstelle bereitstellen, die eine Komponente implementieren kann, und eine API, mit der sie mit Ihrer Anwendung interagieren kann. Dies löst das Problem der Anforderung des Quellcodezugriffs, hat aber immer noch eigene Schwierigkeiten.
Da die Anwendung keine Kapazität für die eigene Erkennung von Komponenten aufweist, muss sie dennoch explizit angewiesen werden, welche Komponenten verfügbar sind und geladen werden sollten. Dies erfolgt in der Regel durch die explizite Registrierung der verfügbaren Komponenten in einer Konfigurationsdatei. Dies bedeutet, dass die Sicherheit, dass die Komponenten korrekt sind, zu einem Wartungsproblem wird, insbesondere, wenn es sich um den Endbenutzer und nicht um den Entwickler handelt, der die Aktualisierung durchführen soll.
Darüber hinaus sind Komponenten nicht in der Lage, miteinander zu kommunizieren, außer durch die starr definierten Kanäle der Anwendung selbst. Wenn der Anwendungsarchitekt die Notwendigkeit einer bestimmten Kommunikation nicht erwartet hat, ist es in der Regel unmöglich.
Schließlich müssen die Komponentenentwickler eine harte Abhängigkeit davon akzeptieren, welche Assembly die von ihnen implementierte Schnittstelle enthält. Dies erschwert die Verwendung einer Komponente in mehr als einer Anwendung und kann auch Probleme verursachen, wenn Sie ein Testframework für Komponenten erstellen.
Was MEF bietet
Statt dieser expliziten Registrierung verfügbarer Komponenten bietet MEF eine Möglichkeit, sie implizit über die Zusammensetzung zu ermitteln. Eine MEF-Komponente, die als Teil bezeichnet wird, gibt deklarativ sowohl ihre Abhängigkeiten (als Importe bezeichnet) als auch welche Funktionen (als Exporte bezeichnet) zur Verfügung gestellt werden. Wenn ein Teil erstellt wird, erfüllt das MEF-Kompositionsmodul seine Importe mit dem, was aus anderen Teilen verfügbar ist.
Dieser Ansatz löst die im vorherigen Abschnitt erörterten Probleme. Da MEF-Teile ihre Funktionen deklarativ angeben, sind sie zur Laufzeit auffindbar, was bedeutet, dass eine Anwendung Teile ohne hartcodierte Verweise oder fragile Konfigurationsdateien verwenden kann. MIT MEF können Anwendungen Teile anhand ihrer Metadaten ermitteln und untersuchen, ohne sie zu instanziieren oder sogar ihre Assemblys zu laden. Daher muss nicht sorgfältig angegeben werden, wann und wie Erweiterungen geladen werden sollen.
Zusätzlich zu den bereitgestellten Exporten können von einem Teil seine Importe angegeben werden, die von anderen Teilen ausgefüllt werden. Dies macht die Kommunikation zwischen Teilen nicht nur möglich, sondern einfach und ermöglicht eine gute Faktorierung von Code. Dienste, die vielen Komponenten gemeinsam sind, können z. B. in einen separaten Teil integriert und einfach geändert oder ersetzt werden.
Da das MEF-Modell keine feste Abhängigkeit von einer bestimmten Anwendungsassembly erfordert, können Erweiterungen von Anwendung zu Anwendung wiederverwendet werden. Dies erleichtert auch die Entwicklung eines Testgerüsts, unabhängig von der Anwendung, zum Testen von Erweiterungskomponenten.
Eine erweiterbare Anwendung, die mit MEF geschrieben wird, deklariert einen Import, der von Erweiterungskomponenten gefüllt werden kann, und kann auch Exporte deklarieren, um Anwendungsdienste für Erweiterungen verfügbar zu machen. Jede Erweiterungskomponente deklariert einen Export und kann auch Importe deklarieren. Auf diese Weise sind Erweiterungskomponenten selbst automatisch erweiterbar.
Wo MEF verfügbar ist
MEF ist in .NET Framework 4 und höheren Versionen und in .NET 5 und höher verfügbar. Sie können MEF in Ihren Clientanwendungen verwenden, unabhängig davon, ob sie Windows Forms, WPF oder eine andere Technologie oder in Serveranwendungen verwenden, die ASP.NET verwenden.
MEF und MAF
In früheren Versionen des .NET Frameworks wurde das verwaltete Add-In Framework (MAF) eingeführt, das es Anwendungen ermöglicht, Erweiterungen zu isolieren und zu verwalten. Der Fokus von MAF liegt auf einer etwas höheren Ebene als MEF und konzentriert sich auf die Isolierung von Erweiterungen sowie das Laden und Entladen von Assemblies, während MEF seinen Schwerpunkt auf Auffindbarkeit, Erweiterbarkeit und Portabilität legt. Die beiden Frameworks funktionieren reibungslos, und eine einzelne Anwendung kann beides nutzen.
SimpleCalculator: Beispielanwendung
Die einfachste Möglichkeit, zu sehen, was MEF tun kann, besteht darin, eine einfache MEF-Anwendung zu erstellen. In diesem Beispiel erstellen Sie einen sehr einfachen Rechner namens SimpleCalculator. Das Ziel von SimpleCalculator besteht darin, eine Konsolenanwendung zu erstellen, die grundlegende arithmetische Befehle in Form "5+3" oder "6-2" akzeptiert und die richtigen Antworten zurückgibt. Mit MEF können Sie neue Operatoren hinzufügen, ohne den Anwendungscode zu ändern.
Informationen zum Herunterladen des vollständigen Codes für dieses Beispiel finden Sie im Beispiel SimpleCalculator (Visual Basic).
Hinweis
Der Zweck von SimpleCalculator besteht darin, die Konzepte und Syntax von MEF zu veranschaulichen, anstatt notwendigerweise ein realistisches Szenario für die Verwendung bereitzustellen. Viele der Anwendungen, die am meisten von der Leistungsfähigkeit von MEF profitieren würden, sind komplexer als SimpleCalculator. Ausführlichere Beispiele finden Sie im Managed Extensibility Framework GitHub.
Erstellen Sie zunächst in Visual Studio ein neues Konsolenanwendungsprojekt, und nennen Sie es
SimpleCalculator.Fügen Sie einen Verweis auf die -Assembly hinzu, in der sich MEF befindet.
Öffnen Sie Module1.vb oder Program.cs, und fügen Sie oder Richtlinien für und hinzu. Diese beiden Namespaces enthalten MEF-Typen, die Sie zum Entwickeln einer erweiterbaren Anwendung benötigen.
Wenn Sie Visual Basic verwenden, fügen Sie das Schlüsselwort
Publicder Zeile hinzu, die das ModulModule1deklariert.
Kompositionscontainer und Kataloge
Der Kern des MEF-Kompositionsmodells ist der Kompositionscontainer, der alle verfügbaren Teile enthält und die Komposition durchführt. Die Zusammensetzung ist das Abstimmen der Importe auf die Exporte. Der gängigste Typ des Kompositionscontainers ist , und Sie verwenden diese für SimpleCalculator.
Wenn Sie Visual Basic verwenden, fügen Sie eine öffentliche Klasse namens Program in Module1.vb hinzu.
Fügen Sie der Klasse in oder Program.cs die folgende Zeile hinzu:
Dim _container As CompositionContainer
private CompositionContainer _container;
Um die verfügbaren Teile zu ermitteln, nutzt die Kompositionscontainer einen Katalog. Ein Katalog ist ein Objekt, das aus einer Quelle ermittelte Teile zur Verfügung stellt. MEF stellt Kataloge bereit, um Teile eines bereitgestellten Typs, einer Assembly oder eines Verzeichnisses zu ermitteln. Anwendungsentwickler können ganz einfach neue Kataloge erstellen, um Teile aus anderen Quellen zu ermitteln, z. B. einen Webdienst.
Fügen Sie der Klasse den folgenden Konstruktor hinzu:
Public Sub New()
' An aggregate catalog that combines multiple catalogs.
Dim catalog = New AggregateCatalog()
' Adds all the parts found in the same assembly as the Program class.
catalog.Catalogs.Add(New AssemblyCatalog(GetType(Program).Assembly))
' Create the CompositionContainer with the parts in the catalog.
_container = New CompositionContainer(catalog)
' Fill the imports of this object.
Try
_container.ComposeParts(Me)
Catch ex As CompositionException
Console.WriteLine(ex.ToString)
End Try
End Sub
private Program()
{
try
{
// An aggregate catalog that combines multiple catalogs.
var catalog = new AggregateCatalog();
// Adds all the parts found in the same assembly as the Program class.
catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
// Create the CompositionContainer with the parts in the catalog.
_container = new CompositionContainer(catalog);
_container.ComposeParts(this);
}
catch (CompositionException compositionException)
{
Console.WriteLine(compositionException.ToString());
}
}
Der Aufruf an sorgt dafür, dass der Kompositionscontainer einen bestimmten Satz von Teilen zusammensetzt, in diesem Fall die aktuelle Instanz von . Zu diesem Zeitpunkt geschieht jedoch nichts, da keine Importe zu füllen hat.
Importe und Exporte mit Attributen
Importieren Sie zunächst mithilfe von einen Rechner. Dies ermöglicht die Trennung von Benutzeroberflächenkomponenten, z. B. der Konsolenein- und -ausgabe, die an geleitet werden, von der Logik des Rechners.
Fügen Sie der -Klasse folgenden Code hinzu:
<Import(GetType(ICalculator))>
Public Property calculator As ICalculator
[Import(typeof(ICalculator))]
public ICalculator calculator;
Beachten Sie, dass die Deklaration des Objekts nicht ungewöhnlich ist, sondern dass sie mit dem Attribut versehen ist. Dieses Attribut deklariert etwas als Import; d. h., es wird vom Kompositionsmodul gefüllt, wenn das Objekt zusammengesetzt wird.
Jeder Import verfügt über einen Vertrag, der bestimmt, mit welchen Exporten es abgeglichen wird. Der Vertrag kann eine explizit angegebene Zeichenfolge sein, oder er kann automatisch von MEF aus einem bestimmten Typ generiert werden, in diesem Fall die Schnittstelle . Jeder Export, der mit einem übereinstimmenden Vertrag deklariert wurde, erfüllt diesen Import. Beachten Sie, dass dies nicht erforderlich ist, während der Typ des Objekts tatsächlich ist. Der Vertrag ist unabhängig vom Typ des importobjekts. (In diesem Fall könnten Sie weglassen. MEF wird automatisch annehmen, dass der Vertrag auf dem Typ des Imports basiert, es sei denn, Sie geben ihn explizit an.)
Fügen Sie dem Modul oder dem -Namespace diese sehr einfache Schnittstelle hinzu:
Public Interface ICalculator
Function Calculate(input As String) As String
End Interface
public interface ICalculator
{
string Calculate(string input);
}
Nachdem Sie nun definiert haben, benötigen Sie eine Klasse, die sie implementiert. Fügen Sie dem Modul oder Namespace die folgende Klasse hinzu:
<Export(GetType(ICalculator))>
Public Class MySimpleCalculator
Implements ICalculator
End Class
[Export(typeof(ICalculator))]
class MySimpleCalculator : ICalculator
{
}
Dieser Export entspricht dem Import in . Damit der Export mit dem Import übereinstimmt, muss der Export über denselben Vertrag verfügen. Beim Export unter einem Vertrag auf Grundlage von wäre ein Konflikt die Folge, und der Import würde nicht ausgefüllt werden. Der Vertrag muss genau übereinstimmen.
Da der Kompositionscontainer mit allen in dieser Assembly verfügbaren Teilen aufgefüllt wird, ist der Teil verfügbar. Wenn der Konstruktor eine Komposition am -Objekt durchführt, wird dessen Import mit einem -Objekt gefüllt, das zu diesem Zweck erstellt wird.
Die Benutzeroberflächenebene () muss nichts anderes wissen. Sie können daher den Rest der Benutzeroberflächenlogik in der Methode ausfüllen.
Fügen Sie der -Methode folgenden Code hinzu:
Sub Main()
' Composition is performed in the constructor.
Dim p As New Program()
Dim s As String
Console.WriteLine("Enter Command:")
While (True)
s = Console.ReadLine()
Console.WriteLine(p.calculator.Calculate(s))
End While
End Sub
static void Main(string[] args)
{
// Composition is performed in the constructor.
var p = new Program();
Console.WriteLine("Enter Command:");
while (true)
{
string s = Console.ReadLine();
Console.WriteLine(p.calculator.Calculate(s));
}
}
Dieser Code liest einfach eine Eingabezeile und ruft die -Funktion von auf das Ergebnis auf, das er wieder in die Konsole schreibt. Das ist der gesamte Code, den Sie in benötigen. Der Rest der Arbeiten wird in den einzelnen Teilen durchgeführt.
Importe und ImportMany-Attribute
Damit SimpleCalculator erweiterbar ist, muss eine Liste von Vorgängen importiert werden. Ein gewöhnliches Attribut wird von einem und nur einem ausgefüllt. Wenn mehrere verfügbar sind, erzeugt das Kompositionsmodul einen Fehler. Um einen Import zu erstellen, der mit einer beliebigen Anzahl von Exporten gefüllt werden kann, können Sie das Attribut verwenden.
Fügen Sie der Klasse die folgende Operations-Eigenschaft hinzu :
<ImportMany()>
Public Property operations As IEnumerable(Of Lazy(Of IOperation, IOperationData))
[ImportMany]
IEnumerable<Lazy<IOperation, IOperationData>> operations;
ist ein Von MEF bereitgestellter Typ, der indirekte Verweise auf Exporte enthält. Zusätzlich zum exportierten Objekt selbst erhalten Sie auch Exportmetadaten oder Informationen, die das exportierte Objekt beschreiben. Jedes enthält ein Objekt, das einen tatsächlichen Vorgang darstellt, und ein Objekt, das seine Metadaten darstellt.
Fügen Sie dem Modul oder Namespace die folgenden einfachen Schnittstellen hinzu:
Public Interface IOperation
Function Operate(left As Integer, right As Integer) As Integer
End Interface
Public Interface IOperationData
ReadOnly Property Symbol As Char
End Interface
public interface IOperation
{
int Operate(int left, int right);
}
public interface IOperationData
{
char Symbol { get; }
}
In diesem Fall ist die Metadaten für jeden Vorgang das Symbol, das diesen Vorgang darstellt, z. B. +, -, *usw. Um den Additionsvorgang verfügbar zu machen, fügen Sie die folgende Klasse zum Modul oder Namespace hinzu:
<Export(GetType(IOperation))>
<ExportMetadata("Symbol", "+"c)>
Public Class Add
Implements IOperation
Public Function Operate(left As Integer, right As Integer) As Integer Implements IOperation.Operate
Return left + right
End Function
End Class
[Export(typeof(IOperation))]
[ExportMetadata("Symbol", '+')]
class Add: IOperation
{
public int Operate(int left, int right)
{
return left + right;
}
}
Das Attribut funktioniert wie zuvor. Das Attribut fügt Metadaten in Form eines Namenswertpaars an diesen Export an. Während die -Klasse implementiert, wird eine Klasse, die implementiert, nicht explizit definiert. Stattdessen wird eine Klasse implizit von MEF mit Eigenschaften basierend auf den Namen der bereitgestellten Metadaten erstellt. (Dies ist eine von mehreren Möglichkeiten, auf Metadaten in MEF zuzugreifen.)
Komposition in MEF ist rekursiv. Sie haben das Objekt explizit erstellt, das ein objekt importiert hat, das sich als Typ erwiesen hat. wiederum importiert eine Sammlung von Objekten, die dann bei der Erstellung von ausgefüllt wird, gleichzeitig mit den Importen von . Wenn die Klasse einen weiteren Import deklariert hat, müsste dies ebenfalls ausgefüllt werden usw. Alle Importe, die nicht ausgefüllt wurden, führen zu einem Kompositionsfehler. (Es ist jedoch möglich, Importe optional zu deklarieren oder ihnen Standardwerte zuzuweisen.)
Rechnerlogik
Sind diese Teile bereitgestellt, bleibt nun noch die Rechnerlogik selbst. Fügen Sie den folgenden Code in der Klasse hinzu, um die Methode zu implementieren:
Public Function Calculate(input As String) As String Implements ICalculator.Calculate
Dim left, right As Integer
Dim operation As Char
' Finds the operator.
Dim fn = FindFirstNonDigit(input)
If fn < 0 Then
Return "Could not parse command."
End If
operation = input(fn)
Try
' Separate out the operands.
left = Integer.Parse(input.Substring(0, fn))
right = Integer.Parse(input.Substring(fn + 1))
Catch ex As Exception
Return "Could not parse command."
End Try
For Each i As Lazy(Of IOperation, IOperationData) In operations
If i.Metadata.symbol = operation Then
Return i.Value.Operate(left, right).ToString()
End If
Next
Return "Operation not found!"
End Function
public String Calculate(string input)
{
int left;
int right;
char operation;
// Finds the operator.
int fn = FindFirstNonDigit(input);
if (fn < 0) return "Could not parse command.";
try
{
// Separate out the operands.
left = int.Parse(input.Substring(0, fn));
right = int.Parse(input.Substring(fn + 1));
}
catch
{
return "Could not parse command.";
}
operation = input[fn];
foreach (Lazy<IOperation, IOperationData> i in operations)
{
if (i.Metadata.Symbol.Equals(operation))
{
return i.Value.Operate(left, right).ToString();
}
}
return "Operation Not Found!";
}
Durch die anfänglichen Schritte wird die Eingabezeichenfolge analysiert und in linke und rechte Operanden sowie in ein Operatorzeichen eingeteilt. In der Schleife wird jedes Element der Sammlung untersucht. Diese Objekte sind vom Typ und deren Metadatenwerte und exportiertes Objekt können mit der Eigenschaft bzw. der Eigenschaft zugegriffen werden. Wenn in diesem Fall die Eigenschaft des Objekts als Übereinstimmung erkannt wird, ruft der Rechner die Methode des Objekts auf und gibt das Ergebnis zurück.
Um den Rechner abzuschließen, benötigen Sie auch eine Hilfsmethode, die die Position des ersten nicht-stelligen Zeichens in einer Zeichenfolge zurückgibt. Fügen Sie der Klasse die folgende Hilfsmethode hinzu:
Private Function FindFirstNonDigit(s As String) As Integer
For i = 0 To s.Length - 1
If Not Char.IsDigit(s(i)) Then Return i
Next
Return -1
End Function
private int FindFirstNonDigit(string s)
{
for (int i = 0; i < s.Length; i++)
{
if (!char.IsDigit(s[i])) return i;
}
return -1;
}
Sie sollten jetzt in der Lage sein, das Projekt zu kompilieren und auszuführen. Stellen Sie in Visual Basic sicher, dass Sie das Schlüsselwort Public zum Module1 hinzugefügt haben. Geben Sie im Konsolenfenster einen Zusatzvorgang ein, z. B. "5+3", und der Rechner gibt die Ergebnisse zurück. Bei jedem anderen Operator erhalten Sie die Meldung „Vorgang nicht gefunden!“.
Erweitern von SimpleCalculator mithilfe einer neuen Klasse
Jetzt, da der Rechner funktioniert, ist das Hinzufügen eines neuen Vorgangs einfach. Fügen Sie dem Modul oder Namespace die folgende Klasse hinzu:
<Export(GetType(IOperation))>
<ExportMetadata("Symbol", "-"c)>
Public Class Subtract
Implements IOperation
Public Function Operate(left As Integer, right As Integer) As Integer Implements IOperation.Operate
Return left - right
End Function
End Class
[Export(typeof(IOperation))]
[ExportMetadata("Symbol", '-')]
class Subtract : IOperation
{
public int Operate(int left, int right)
{
return left - right;
}
}
Kompilieren sie das Projekt, und führen Sie es aus. Geben Sie einen Subtraktionsvorgang ein, z. B. "5-3". Der Rechner unterstützt jetzt Subtraktion sowie Addition.
Erweitern von SimpleCalculator mithilfe einer neuen Assembly
Das Hinzufügen von Klassen zum Quellcode ist einfach genug, aber MEF bietet die Möglichkeit, außerhalb der eigenen Quelle einer Anwendung nach Teilen zu suchen. Um dies zu veranschaulichen, müssen Sie SimpleCalculator so ändern, dass sowohl ein Verzeichnis als auch seine eigene Assembly nach Teilen durchsucht werden, indem ein hinzugefügt wird.
Fügen Sie dem SimpleCalculator-Projekt ein neues Verzeichnis hinzu . Stellen Sie sicher, dass Sie es auf Projektebene und nicht auf Lösungsebene hinzufügen. Fügen Sie dann der Projektmappe mit dem Namen ein neues Klassenbibliotheksprojekt hinzu. Das neue Projekt wird in einer separaten Assembly kompiliert.
Öffnen Sie den Projekteigenschaften-Designer für das ExtendedOperations-Projekt, und klicken Sie auf die Registerkarte " Kompilieren " oder " Erstellen ". Ändern Sie den Buildausgabepfad oder Ausgabepfad so, dass er auf das Verzeichnis "Erweiterungen" im Projektverzeichnis "SimpleCalculator" (.) verweist. \SimpleCalculator\Extensions\).
Fügen Sie in Module1.vb oder Program.cs die folgende Zeile zum Konstruktor hinzu:
catalog.Catalogs.Add(
New DirectoryCatalog(
"C:\SimpleCalculator\SimpleCalculator\Extensions"))
catalog.Catalogs.Add(
new DirectoryCatalog(
"C:\\SimpleCalculator\\SimpleCalculator\\Extensions"));
Ersetzen Sie den Beispielpfad durch den Pfad zu Ihrem Erweiterungsverzeichnis. (Dieser absolute Pfad dient nur zum Debuggen. In einer Produktionsanwendung würden Sie einen relativen Pfad verwenden.) Dadurch werden nun alle Teile hinzugefügt, die in allen Assemblys im Erweiterungsverzeichnis zum Kompositionscontainer gefunden werden.
Fügen Sie im Projekt Verweise auf und . Fügen Sie in der Klassendatei eine oder eine Direktive für . Fügen Sie in Visual Basic auch eine Imports-Anweisung für SimpleCalculator hinzu. Fügen Sie dann der Klassendatei die folgende Klasse hinzu:
<Export(GetType(SimpleCalculator.IOperation))>
<ExportMetadata("Symbol", "%"c)>
Public Class Modulo
Implements IOperation
Public Function Operate(left As Integer, right As Integer) As Integer Implements IOperation.Operate
Return left Mod right
End Function
End Class
[Export(typeof(SimpleCalculator.IOperation))]
[ExportMetadata("Symbol", '%')]
public class Mod : SimpleCalculator.IOperation
{
public int Operate(int left, int right)
{
return left % right;
}
}
Beachten Sie, dass das Attribut denselben Typ wie haben muss, damit der Vertrag übereinstimmen kann.
Kompilieren sie das Projekt, und führen Sie es aus. Testen Sie den neuen MOD (%)-Operator.
Conclusion
In diesem Thema wurden die grundlegenden Konzepte von MEF behandelt.
Teile, Kataloge und der Kompositionscontainer
Teile und der Kompositionscontainer sind die grundlegenden Bausteine einer MEF-Anwendung. Ein Teil ist ein beliebiges Objekt, das einen Wert importiert oder exportiert, einschließlich sich selbst. Ein Katalog stellt eine Sammlung von Teilen aus einer bestimmten Quelle bereit. Der Kompositionscontainer verwendet die von einem Katalog bereitgestellten Teile, um die Komposition durchzuführen, die Bindung von Importen an Exporte.
Importe und Exporte
Importe und Exporte sind die Art und Weise, wie Komponenten kommunizieren. Bei einem Import spezifiziert die Komponente einen bestimmten Wert oder ein bestimmtes Objekt, und mit einem Export spezifiziert sie die Verfügbarkeit eines bestimmten Wertes. Jeder Import wird anhand seines Vertrags mit einer Reihe von Exporten verglichen.
Nächste Schritte
Informationen zum Herunterladen des vollständigen Codes für dieses Beispiel finden Sie im Beispiel SimpleCalculator (Visual Basic).
Weitere Informationen und Codebeispiele finden Sie unter Managed Extensibility Framework. Eine Liste der MEF-Typen finden Sie im Namespace.