Erweiterbare Objekte
Das erweiterbare Objektmuster wird verwendet, um entweder vorhandene Laufzeitklassen um neue Funktionen zu erweitern oder um einem Objekt neue Zustandsfunktionen hinzuzufügen. Erweiterungen, die einem der erweiterbaren Objekte zugeordnet sind, ermöglichen es Verhalten in verschiedenen Phasen der Verarbeitung, auf gemeinsam verwendete Zustände und Funktionen zuzugreifen, die an ein zugängliches und allgemeines erweiterbares Objekt angefügt sind.
Das IExtensibleObject<T>-Muster
Es gibt drei Schnittstellen im erweiterbaren Objektmuster: IExtensibleObject, IExtension und IExtensionCollection.
Die IExtensibleObject-Schnittstelle wird von Typen implementiert, die es IExtension-Objekten ermöglichen, ihre Funktionalität anzupassen.
Erweiterbare Objekte ermöglichen die dynamische Aggregation von IExtension-Objekten. IExtension-Objekte sind durch die folgende Schnittstelle gekennzeichnet:
public interface IExtension<T>
where T : IExtensibleObject<T>
{
void Attach(T owner);
void Detach(T owner);
}
Die Typbeschränkung stellt sicher, dass Erweiterungen nur für Klassen definiert werden können, für die IExtensibleObject gilt. Attach und Detach führen die Benachrichtigung über eine Aggregation oder Disaggregation durch.
Bei Implementierungen können Beschränkungen verwendet werden, wenn sie einem Besitzer hinzugefügt bzw. wenn sie entfernt werden. Sie können zum Beispiel die Entfernung vollständig unmöglich machen, indem Sie das Hinzufügen oder Entfernen von Erweiterungen untersagen, wenn sich der Besitzer oder die Erweiterung in einem bestimmten Zustand befinden, das gleichzeitige Hinzufügen zu mehreren Besitzern untersagen oder nur eine einzelne Hinzufügung gefolgt von einer einzelnen Entfernung zulassen.
IExtension impliziert keine Interaktionen mit anderen standardmäßigen verwalteten Schnittstellen. Die System.IDisposable.Dispose-Methode des Besitzerobjekts trennt ihre Erweiterungen in der Regel nicht ab.
Wenn der Auflistung eine Erweiterung hinzugefügt wird, wird Attach aufgerufen, bevor die Erweiterung in die Auflistung aufgenommen wird. Wenn eine Erweiterung aus der Auflistung entfernt wird, wird nach der Entfernung Detach aufgerufen. Dies bedeutet (vorausgesetzt, es erfolgt eine entsprechende Synchronisierung), dass eine Erweiterung nur dann sicher in einer Auflistung enthalten ist, wenn sie sich zwischen den Zuständen Attach und Detach befindet.
Für das Objekt, das an FindAll oder Find übergeben wird, muss nicht IExtension gelten (beispielsweise können Sie jedes Objekt übergeben), aber bei der zurückgegebenen Erweiterung handelt es sich um IExtension.
Wenn keine Erweiterung in der Auflistung eine IExtension ist, gibt Find NULL und FindAll eine leere Auflistung zurück. Wenn mehrere Erweiterungen IExtension implementieren, gibt Find eine davon zurück. Der von FindAll zurückgegebene Wert ist eine Momentaufnahme.
Es gibt zwei Hauptszenarios. Beim ersten Szenario wird die Extensions-Eigenschaft als typbasiertes Wörterbuch verwendet, um den Zustand für ein Objekt einzufügen und auf diese Weise eine andere Komponente in die Lage zu versetzen, anhand des Typs danach zu suchen.
Beim zweiten Szenario werden die Eigenschaften Attach und Detach verwendet, um einem Objekt die Teilnahme am benutzerdefinierten Verhalten zu ermöglichen, zum Beispiel das Registrieren von Ereignissen, Beobachten von Zustandsübergängen usw.
Die IExtensionCollection-Schnittstelle ist eine Auflistung der IExtension-Objekte, die das Abrufen der IExtension anhand des Typs zulassen. System.ServiceModel.IExtensionCollection.Find gibt das zuletzt hinzugefügte Objekt zurück, das eine IExtension dieses Typs ist.
Erweiterbare Objekte in Windows Communication Foundation
Es gibt vier erweiterbare Objekte in Windows Communication Foundation (WCF):
ServiceHostBase – Dies ist die Basisklasse für den Host des Dienstes. Sie können die Erweiterungen dieser Klasse verwenden, um das Verhalten von ServiceHostBase selbst zu erweitern oder um den Zustand für die Dienste einzeln zu speichern.
InstanceContext – Diese Klasse verbindet eine Instanz des Diensttyps mit der Dienstlaufzeit. Sie enthält Informationen zu der Instanz sowie einen Verweis auf den InstanceContext, der ServiceHostBase enthält. Sie können die Erweiterungen dieser Klasse verwenden, um das Verhalten von InstanceContext zu erweitern oder um den Zustand für die Dienste einzeln zu speichern.
OperationContext – Diese Klasse stellt die Vorgangsinformationen dar, die die Laufzeit für jeden Vorgang aufzeichnet. Dazu gehören auch Informationen wie Header von eingehenden Nachrichten, Eigenschaften von eingehenden Nachrichten, die eingehende Sicherheitsidentität und andere Informationen. Erweiterungen dieser Klasse können entweder das Verhalten des OperationContext erweitern oder den Zustand für jeden Vorgang einzeln speichern.
IContextChannel – Diese Schnittstelle ermöglicht die Untersuchung der einzelnen Zustände für die Kanäle und Proxys, die von der WCF-Laufzeit erstellt werden. Erweiterungen dieser Klasse können entweder das Verhalten des IClientChannel erweitern oder das Verhalten verwenden, um den Zustand für jeden Kanal einzeln zu speichern.
Das folgende Codebeispiel zeigt die Verwendung einer einfachen Erweiterung zum Verfolgen von InstanceContext-Objekten.