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.
Das erweiterbare Objektmuster wird zum Erweitern vorhandener Laufzeitklassen mit neuer Funktionalität oder zum Hinzufügen eines neuen Zustands zu einem Objekt verwendet. Erweiterungen, die an eines der erweiterbaren Objekte angefügt sind, ermöglichen Verhaltensweisen in sehr unterschiedlichen Phasen der Verarbeitung für den Zugriff auf gemeinsam genutzten Zustand und die Funktionalität, die einem gemeinsamen erweiterbaren Objekt zugeordnet ist, auf das sie zugreifen können.
Das IExtensibleObject<T-Muster>
Es gibt drei Schnittstellen im erweiterbaren Objektmuster: IExtensibleObject<T>, , IExtension<T>und IExtensionCollection<T>.
Die IExtensibleObject<T> Schnittstelle wird durch Typen implementiert, mit denen Objekte ihre Funktionalität anpassen können IExtension<T> .
Erweiterbare Objekte ermöglichen die dynamische Aggregation von IExtension<T> Objekten. IExtension<T> Objekte zeichnen sich durch die folgende Schnittstelle aus:
public interface IExtension<T>
where T : IExtensibleObject<T>
{
void Attach(T owner);
void Detach(T owner);
}
Die Typbeschränkung garantiert, dass Erweiterungen nur für Klassen definiert werden können, die IExtensibleObject<T> sind. Attach und Detach bieten Benachrichtigungen über Aggregation oder Disaggregation an.
Bei Implementierungen können Beschränkungen verwendet werden, wenn sie einem Besitzer hinzugefügt bzw. wenn sie entfernt werden. Sie können z. B. das Entfernen vollständig verbieten, das Hinzufügen oder Entfernen von Erweiterungen aufheben, wenn sich der Besitzer oder die Erweiterung in einem bestimmten Zustand befinden, das Gleichzeitige Hinzufügen zu mehreren Besitzern verbieten oder nur eine einzelne Ergänzung zulassen, gefolgt von einer einzelnen Entfernung.
IExtension<T> impliziert keine Interaktionen mit anderen standardverwalteten Schnittstellen. Die 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 Detach nach dem Entfernen aufgerufen. Dies bedeutet (vorausgesetzt die richtige Synchronisierung), dass eine Erweiterung sich darauf verlassen kann, nur in der Auflistung gefunden zu werden, während sie zwischen Attach und Detach ist.
Das Objekt, das an FindAll oder Find übergeben wird, muss kein IExtension<T> sein (zum Beispiel können Sie ein beliebiges Objekt übergeben), aber die zurückgegebene Erweiterung ist ein IExtension<T>.
Wenn in der Auflistung keine Erweiterung IExtension<T> enthalten ist, gibt Find null zurück, und FindAll gibt eine leere Auflistung zurück. Wenn mehrere Erweiterungen IExtension<T> implementieren, gibt Find eine von ihnen zurück. Der von FindAll zurückgegebene Wert ist eine Momentaufnahme.
Es gibt zwei Hauptszenarien. Im ersten Szenario wird die Extensions Eigenschaft als typbasiertes Wörterbuch verwendet, um den Zustand eines Objekts einzufügen, damit eine andere Komponente sie mithilfe des Typs nachschlagen kann.
Das zweite Szenario verwendet die Eigenschaften Attach und Detach, um einem Objekt die Teilnahme an benutzerdefiniertem Verhalten zu ermöglichen, wie etwa die Registrierung für Ereignisse, das Überwachen von Zustandsübergängen und so weiter.
Die IExtensionCollection<T> Schnittstelle ist eine Sammlung der IExtension<T> Objekte, die das Abrufen des IExtension<T> anhand dessen Typs ermöglichen. IExtensionCollection<T>.Find gibt das zuletzt hinzugefügte Objekt zurück, bei dem es sich um ein IExtension<T> Objekt dieses Typs handelt.
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 Diensts. Erweiterungen dieser Klasse können verwendet werden, um das Verhalten des ServiceHostBase selbst zu erweitern oder den Zustand für jeden Dienst 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. Erweiterungen dieser Klasse können verwendet werden, um das Verhalten des InstanceContext Oder zum Speichern des Zustands für jeden Dienst zu erweitern.
OperationContext – Diese Klasse stellt die Vorgangsinformationen dar, die von der Laufzeit für jeden Vorgang gesammelt werden. 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 OperationContext der einzelnen Vorgänge erweitern oder den Zustand speichern.
IContextChannel – Diese Schnittstelle ermöglicht die Überprüfung jedes Zustands für die Kanäle und Proxys, die von der WCF-Laufzeit erstellt wurden. Erweiterungen dieser Klasse können entweder das Verhalten IClientChannel erweitern oder verwenden, um den Zustand für jeden Kanal zu speichern.
Das folgende Codebeispiel zeigt die Verwendung einer einfachen Erweiterung zum Nachverfolgen InstanceContext von Objekten.
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
namespace Microsoft.WCF.Documentation
{
public class MyInstanceContextInitializer : IInstanceContextInitializer
{
public void Initialize(InstanceContext instanceContext, Message message)
{
MyInstanceContextExtension extension = new MyInstanceContextExtension();
//Add your custom InstanceContext extension that will let you associate state with this instancecontext
instanceContext.Extensions.Add(extension);
}
}
//Create an Extension that will attach to each InstanceContext and let it retrieve the Id or whatever state you want to associate
public class MyInstanceContextExtension : IExtension<InstanceContext>
{
//Associate an Id with each Instance Created.
string _instanceId;
public MyInstanceContextExtension()
{ _instanceId = Guid.NewGuid().ToString(); }
public string InstanceId => _instanceId;
public void Attach(InstanceContext owner)
{
Console.WriteLine("Attached to new InstanceContext.");
}
public void Detach(InstanceContext owner)
{
Console.WriteLine("Detached from InstanceContext.");
}
}
public class InstanceInitializerBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParameters)
{ }
//Apply the custom IInstanceContextProvider to the EndpointDispatcher.DispatchRuntime
public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
{
MyInstanceContextInitializer extension = new MyInstanceContextInitializer();
endpointDispatcher.DispatchRuntime.InstanceContextInitializers.Add(extension);
}
public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
{ }
public void Validate(ServiceEndpoint endpoint)
{ }
}
public class InstanceInitializerBehaviorExtensionElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof(InstanceInitializerBehavior); }
}
protected override object CreateBehavior()
{
return new InstanceInitializerBehavior();
}
}
}