Konfigurieren und Erweitern der Laufzeit mit Verhalten

Verhalten ermöglichen es, das Standardverhalten zu ändern und benutzerdefinierte Erweiterungen hinzuzufügen, die die Dienstkonfiguration überprüfen, oder das Laufzeitverhalten in WCF-Client- und Dienstanwendungen (Windows Communication Foundation) zu ändern. In diesem Thema werden die Verhaltensschnittstellen beschrieben und erläutert, wie sie implementiert und wie sie zur Dienstbeschreibung (in einer Dienstanwendung) oder zu einem Endpunkt (in einer Clientanwendung) programmgesteuert oder in einer Konfigurationsdatei hinzugefügt werden können. Weitere Informationen zu den vom System bereitgestellten Verhalten finden Sie unter Angeben des Dienstlaufzeitverhaltens und Angeben des Clientlaufzeitverhaltens.

Verhalten

Verhaltenstypen werden den Beschreibungsobjekten von Diensten oder Dienstendpunkten (auf der Dienst- bzw. Clientseite) hinzugefügt, bevor diese Objekte von Windows Communication Foundation (WCF) zum Erstellen einer Laufzeit verwendet werden, die einen WCF-Dienst oder -Client ausführt. Wenn diese Verhaltenstypen während des Lauftzeitkonstruktionsprozesses aufgerufen werden, können sie auf Laufzeiteigenschaften und -methoden zugreifen, die die vom Vertrag, von den Bindungen und von den Adressen erstellte Laufzeit ändern.

Verhaltensmethoden

Alle Verhaltenstypen verfügen über eine AddBindingParameters-Methode, eine ApplyDispatchBehavior-Methode, eine Validate-Methode und eine ApplyClientBehavior-Methode mit einer Ausnahme: Da IServiceBehavior nicht in einem Client ausgeführt werden kann, wird ApplyClientBehavior nicht implementiert.

  • Verwenden Sie die AddBindingParameters-Methode, um benutzerdefinierte Objekte zu ändern oder einer Sammlung hinzuzufügen, auf die benutzerdefinierte Bindungen beim Erstellen der Laufzeit für ihre Verwendung zugreifen können. Ein Beispiel hierfür ist, wie Schutzanforderungen festgelegt werden, die beeinflussen, wie der Kanal erstellt wird, jedoch dem Kanalentwickler nicht bekannt sind.

  • Verwenden Sie die Validate-Methode, um die Beschreibungsstruktur und das entsprechende Laufzeitobjekt zu untersuchen und sicherzustellen, dass es einen bestimmten Satz von Kriterien erfüllt.

  • Verwenden Sie die ApplyDispatchBehavior-Methode und die ApplyClientBehavior-Methode, um die Beschreibungsstruktur zu untersuchen und die Laufzeit für einen bestimmten Bereich entweder im Dienst oder auf dem Client zu ändern. Sie können auch Erweiterungsobjekte einfügen.

    Hinweis

    Obwohl eine Beschreibungsstruktur in diesen Methoden bereitgestellt wird, dient sie nur zur Überprüfung. Wenn eine Beschreibungsstruktur geändert wird, ist das Verhalten nicht definiert.

Der Zugriff auf die Eigenschaften, die Sie ändern können, und die Anpassungsschnittstellen, die Sie implementieren können, erfolgt über die Dienst- und Clientlaufzeitklassen. Die Diensttypen sind die Klassen DispatchRuntime und DispatchOperation. Die Clienttypen sind die ClientRuntime-Klasse und die ClientOperation-Klasse. Die ClientRuntime-Klasse und die DispatchRuntime-Klasse sind Erweiterungseinstiegspunkte, um clientweit und dienstweit auf Laufzeiteigenschaften bzw. Erweiterungssammlungen zuzugreifen. Entsprechend machen die ClientOperation-Klasse und die DispatchOperation-Klasse Laufzeiteigenschaften von Client- und Dienstvorgängen bzw. Erweiterungssammlungen verfügbar. Sie können jedoch auf das breiter angelegte Laufzeitobjekt vom Vorgangslaufzeitobjekt aus und umgekehrt zugreifen, sofern erforderlich.

Hinweis

Eine Erläuterung der Laufzeiteigenschaften und Erweiterungstypen, die Sie zum Ändern des Ausführungsverhaltens eines Clients verwenden können, finden Sie unter Erweitern von Clients. Eine Erläuterung der Laufzeiteigenschaften und Erweiterungstypen, die Sie zum Ändern des Ausführungsverhaltens eines Dienstverteilers verwenden können, finden Sie unter Erweitern von Dienstverteilern.

Die meisten WCF-Benutzer*innen interagieren nicht direkt mit der Laufzeit. Stattdessen verwenden sie Kernkonstrukte von Programmiermodellen wie Endpunkte, Verträge, Bindungen, Adressen und Verhaltensattribute für Klassen oder Verhalten in Konfigurationsdateien. Diese Konstrukte bilden die Beschreibungsstruktur. Dies ist die vollständige Spezifikation für die Erstellung einer Laufzeit zur Unterstützung eines von der Beschreibungsstruktur beschriebenen Diensts oder Clients.

Es gibt vier Arten von Verhalten in WCF:

Sie können diese Verhaltenstypen zu verschiedenen Beschreibungsobjekten hinzufügen, indem Sie benutzerdefinierte Attribute implementieren, Anwendungskonfigurationsdateien verwenden oder sie direkt zur Verhaltenssammlung des entsprechenden Beschreibungsobjekts hinzufügen. Sie müssen jedoch zu einer Dienstbeschreibung oder einem Dienstendpunkt-Beschreibungsobjekt hinzugefügt werden, bevor ICommunicationObject.Open auf dem ServiceHost oder einer ChannelFactory<TChannel> aufgerufen wird.

Verhaltensbereiche

Es stehen vier Verhaltenstypen zur Verfügung, die jeweils einem bestimmten Bereich des Laufzeitzugriffs entsprechen.

Dienstverhalten

Dienstverhalten, das IServiceBehavior implementiert, ist der Hauptmechanismus, mit dem die gesamte Dienstlaufzeit geändert wird. Für das Hinzufügen von Dienstverhalten zu einem Dienst stehen drei Mechanismen zur Verfügung.

  1. Verwenden eines Attributs in der Dienstklasse. Wenn ein ServiceHost-Objekt erstellt wird, wird von der ServiceHost-Implementierung Spiegelung eingesetzt, um den Attributsatz für den Diensttyp zu ermitteln. Falls eines der Attribute Implementierungen von IServiceBehavior darstellt, wird es der Verhaltenssammlung für ServiceDescription hinzugefügt. Dadurch können diese Verhaltenstypen an der Erstellung der Dienstlaufzeit partizipieren.

  2. Programmgesteuertes Hinzufügen des Verhaltens zur Verhaltenssammlung in ServiceDescription. Dies kann durch die folgenden Codezeilen erreicht werden:

    ServiceHost host = new ServiceHost(/* Parameters */);  
    host.Description.Behaviors.Add(/* Service Behavior */);  
    
  3. Implementieren eines benutzerdefinierten BehaviorExtensionElement, das die Konfiguration erweitert. Dies ermöglicht die Verwendung des Dienstverhaltens von Anwendungskonfigurationsdateien aus.

Beispiele für das Dienstverhalten in WCF beinhalten das ServiceBehaviorAttribute-Attribut, das ServiceThrottlingBehavior-Verhalten und das ServiceMetadataBehavior-Verhalten.

Vertragsverhalten

Vertragsverhalten, das die IContractBehavior-Schnittstelle implementiert, dient zur Erweiterung der Client- sowie Dienstlaufzeit in einem Vertrag.

Für das Hinzufügen von Vertragsverhalten zu einem Vertrag stehen zwei Mechanismen zur Verfügung. Der erste Mechanismus besteht im Erstellen eines benutzerdefinierten Attributs zur Verwendung in der Vertragsschnittstelle. Wird eine Vertragsschnittstelle entweder an ServiceHost oder ChannelFactory<TChannel> übergeben, untersucht WCF die Attribute für die Schnittstelle. Falls eines der Attribute Implementierungen von IContractBehavior darstellt, wird es der Verhaltenssammlung in der für diese Schnittstelle erstellten System.ServiceModel.Description.ContractDescription hinzugefügt.

Sie können das System.ServiceModel.Description.IContractBehaviorAttribute auch im benutzerdefinierten Vertragsverhaltensattribut implementieren. In diesem Fall sieht das Verhalten wie folgt aus bei der Anwendung auf:

• Eine Vertragsschnittstelle. In diesem Fall wird das Verhalten für jeden beliebigen Endpunkt auf alle Verträge dieses Typs angewendet, und WCF ignoriert den Wert der IContractBehaviorAttribute.TargetContract-Eigenschaft.

• Eine Dienstklasse. In diesem Fall wird das Verhalten nur auf Endpunkte angewendet, deren Vertrag der Wert der TargetContract-Eigenschaft ist.

• Eine Rückrufklasse. In diesem Fall wird das Verhalten auf den Endpunkt des Duplexclients angewendet, und WCF ignoriert den Wert der TargetContract-Eigenschaft.

Der zweite Mechanismus besteht im Hinzufügen des Verhaltens zur Verhaltenssammlung einer ContractDescription.

Beispiele für das Vertragsverhalten in WCF beinhalten das System.ServiceModel.DeliveryRequirementsAttribute-Attribut. Weitere Informationen und ein Beispiel hierzu finden Sie im Verweisthema.

Endpunktverhalten

Endpunktverhalten, das IEndpointBehavior implementiert, ist der Hauptmechanismus, mit dem die gesamte Dienst- oder Clientlaufzeit für einen bestimmten Endpunkt geändert wird.

Für das Hinzufügen von Endpunktverhalten zu einem Dienst stehen zwei Mechanismen zur Verfügung.

  1. Hinzufügen des Verhaltens zur Behaviors-Eigenschaft.

  2. Implementieren eines benutzerdefinierten BehaviorExtensionElement, das die Konfiguration erweitert.

Weitere Informationen und ein Beispiel hierzu finden Sie im Verweisthema.

Vorgangsverhalten

Vorgangsverhalten, das die IOperationBehavior-Schnittstelle implementiert, dient zur Erweiterung der Client- sowie Dienstlaufzeit für jeden Vorgang.

Für das Hinzufügen von Vorgangsverhalten zu einem Vorgang stehen zwei Mechanismen zur Verfügung. Der erste Mechanismus besteht im Erstellen eines benutzerdefinierten Attributs zur Verwendung in der Methode, die den Vorgang formt. Wird ein Vorgang entweder ServiceHost oder ChannelFactory hinzugefügt, fügt WCF jedes IOperationBehavior-Attribut zur Verhaltenssammlung in der für diesen Vorgang erstellten OperationDescription hinzu.

Der zweite Mechanismus besteht im direkten Hinzufügen des Verhaltens zur Verhaltenssammlung einer konstruierten OperationDescription.

Beispiele für das Vorgangsverhalten in WCF beinhalten OperationBehaviorAttribute und TransactionFlowAttribute.

Weitere Informationen und ein Beispiel hierzu finden Sie im Verweisthema.

Verwenden der Konfiguration zur Erstellung von Verhalten

Dienst-, Endpunkt- und Vertragsverhalten können so konzipiert werden, dass sie in Code oder mithilfe von Attributen angegeben werden. Nur Dienst- und Endpunktverhalten können mit Anwendungs- oder Webkonfigurationsdateien konfiguriert werden. Durch das Verfügbarmachen von Verhalten mit Attributen können Entwickler*innen ein Verhalten zur Kompilierungszeit angeben, das zur Laufzeit nicht hinzugefügt, entfernt oder geändert werden kann. Dies ist häufig für Verhalten nützlich, das für den korrekten Betrieb eines Diensts immer erforderlich ist (z. B. die transaktionsbezogenen Parameter für das System.ServiceModel.ServiceBehaviorAttribute-Attribut). Durch Verfügbarmachen von Verhalten unter Verwendung der Konfiguration können Entwickler die Spezifikation und Konfiguration des Verhaltens den Personen überlassen, die den Dienst bereitstellen. Dieses Verfahren ist nützlich für Verhalten, das aus optionalen Komponenten oder einer anderen bereitstellungsspezifischen Konfiguration besteht, wie z. B. ob Metadaten für den Dienst verfügbar gemacht werden oder die spezifische Autorisierungskonfiguration für einen Dienst.

Hinweis

Sie können konfigurationsunterstützendes Verhalten auch zur Durchsetzung von Unternehmensrichtlinien verwenden, indem sie in die Konfigurationsdatei machine.config eingefügt werden und diese Elemente gesperrt werden. Eine Beschreibung und ein Beispiel finden Sie unter Vorgehensweise: Sperren von Endpunkten im Unternehmen.

Um ein Verhalten unter Verwendung der Konfiguration verfügbar zu machen, muss ein Entwickler eine abgeleitete Klasse von BehaviorExtensionElement erstellen und die Erweiterung anschließend in der Konfiguration registrieren.

Das folgende Codebeispiel veranschaulicht, wie BehaviorExtensionElement von IEndpointBehavior implementiert wird:

// BehaviorExtensionElement members  
public override Type BehaviorType  
{  
  get { return typeof(EndpointBehaviorMessageInspector); }  
}  
  
protected override object CreateBehavior()  
{  
  return new EndpointBehaviorMessageInspector();  
}  

Damit das Konfigurationssystem ein benutzerdefiniertes BehaviorExtensionElement laden kann, muss es als Erweiterung registriert werden. Das folgende Codebeispiel zeigt die Konfigurationsdatei für das vorhergehende Endpunktverhalten:

<configuration>  
  <system.serviceModel>  
    <services>  
      <service
        name="Microsoft.WCF.Documentation.SampleService"  
        behaviorConfiguration="metadataSupport"  
      >  
        <host>  
          <baseAddresses>  
            <add baseAddress="http://localhost:8080/ServiceMetadata" />  
          </baseAddresses>  
        </host>  
        <endpoint  
          address="/SampleService"  
          binding="wsHttpBinding"  
          behaviorConfiguration="withMessageInspector"
          contract="Microsoft.WCF.Documentation.ISampleService"  
        />  
        <endpoint  
           address="mex"  
           binding="mexHttpBinding"  
           contract="IMetadataExchange"  
        />  
      </service>  
    </services>  
    <behaviors>  
      <serviceBehaviors>  
      <behavior name="metadataSupport">  
        <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>  
      </behavior>  
      </serviceBehaviors>  
      <endpointBehaviors>  
        <behavior name="withMessageInspector">  
          <endpointMessageInspector />  
        </behavior>  
      </endpointBehaviors>  
    </behaviors>  
    <extensions>  
      <behaviorExtensions>  
        <add
          name="endpointMessageInspector"  
          type="Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector, HostApplication, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"  
        />  
      </behaviorExtensions>  
    </extensions>  
  </system.serviceModel>  
</configuration>  

Dabei gilt: Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector ist der Verhaltenserweiterungstyp und HostApplication der Name der Assembly, in die diese Klasse kompiliert wurde.

Auswertungsreihenfolge

Die System.ServiceModel.ChannelFactory<TChannel> und der System.ServiceModel.ServiceHost sind für das Erstellen der Laufzeit aus dem Programmierungsmodell und der Beschreibung verantwortlich. Verhaltenstypen, wie zuvor beschrieben, tragen zu diesem Erstellungsprozess auf der Dienst-, Endpunkt-, Vertrags- und Vorgangsebene bei.

Der ServiceHost wendet Verhalten in folgender Reihenfolge an:

  1. Dienst

  2. Vertrag

  3. Endpunkt

  4. Vorgang

Innerhalb einer Verhaltenssammlung wird keine Reihenfolge garantiert.

Der ChannelFactory<TChannel> wendet Verhalten in folgender Reihenfolge an:

  1. Vertrag

  2. Endpunkt

  3. Vorgang

Innerhalb einer Verhaltenssammlung wird auch in diesem Fall keine Reihenfolge garantiert.

Programmgesteuertes Hinzufügen von Verhalten

Eigenschaften von System.ServiceModel.Description.ServiceDescription in der Dienstanwendung dürfen nicht im Anschluss an die CommunicationObject.OnOpening-Methode auf System.ServiceModel.ServiceHostBase geändert werden. Einige Member, wie die ServiceHostBase.Credentials-Eigenschaft und die AddServiceEndpoint-Methoden auf ServiceHostBase und System.ServiceModel.ServiceHost, lösen eine Ausnahme aus, wenn eine Änderung über diesen Punkt hinaus stattfindet. Andere Member können geändert werden, wobei das Ergebnis jedoch nicht definiert ist.

Ähnlich verhält es sich mit den System.ServiceModel.Description.ServiceEndpoint-Werten, die auf dem Client nach dem Aufruf von OnOpening auf System.ServiceModel.ChannelFactory nicht geändert werden dürfen. Die ChannelFactory.Credentials-Eigenschaft löst eine Ausnahme aus, wenn sie über diesen Punkt hinaus geändert wird. Die anderen Clientbeschreibungswerte können jedoch ohne Fehler geändert werden. Das Ergebnis ist allerdings nicht definiert.

Sowohl für den Dienst als auch den Client wird empfohlen, die Beschreibung vor dem Aufruf von CommunicationObject.Open zu ändern.

Vererbungsregeln für Verhaltensattribute

Alle vier Verhaltenstypen können mit Attributen aufgefüllt werden – Dienstverhalten und Vertragsverhalten. Da Attribute für verwaltete Objekte und Member definiert werden und verwaltete Objekte und Member die Vererbung unterstützen, ist es notwendig zu definieren, wie Verhaltensattribute im Vererbungskontext funktionieren.

Auf höherer Ebene gilt die Regel, dass für einen bestimmten Bereich (z. B. Dienst, Vertrag oder Vorgang) alle Verhaltensattribute in der Vererbungshierarchie für diesen Bereich angewendet werden. Wenn zwei Verhaltensattribute desselben Typs vorhanden sind, wird nur der Typ mit den meisten Ableitungen verwendet.

Dienstverhalten

Für eine bestimmte Dienstklasse werden alle Dienstverhaltensattribute für diese Klasse und für übergeordnete Elemente dieser Klasse angewendet. Wenn derselbe Attributtyp an mehreren Stellen der Vererbungshierarchie angewendet wird, wird nur der Typ mit den meisten Ableitungen verwendet.

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]  
[AspNetCompatibilityRequirementsAttribute(  
    AspNetCompatibilityRequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]  
public class A { /* … */ }  
  
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
public class B : A { /* … */}  

Im vorhergehenden Fall weist der Dienst B am Ende den InstanceContextMode-Modus Single, den AspNetCompatibilityRequirementsMode-Modus Allowed und den ConcurrencyMode-Modus Single auf. Der ConcurrencyMode-Modus lautet Single, da das ServiceBehaviorAttribute-Attribut für den Dienst B "mehr Ableitungen" aufweist als Dienst A.

Vertragsverhalten

Für einen bestimmten Vertrag werden alle Vertragsverhaltensattribute für diese Schnittstelle und für übergeordnete Elemente dieser Schnittstelle angewendet. Wenn derselbe Attributtyp an mehreren Stellen der Vererbungshierarchie angewendet wird, wird nur der Typ mit den meisten Ableitungen verwendet.

Vorgangsverhalten

Wenn ein bestimmter Vorgang einen vorhandenen abstrakten oder virtuellen Vorgang nicht überschreibt, werden keine Vererbungsregeln angewendet.

Wenn ein Vorgang einen vorhandenen Vorgang überschreibt, werden alle Vorgangsverhaltensattribute für diesen Vorgang und für die übergeordneten Elemente dieses Vorgangs angewendet. Wenn derselbe Attributtyp an mehreren Stellen der Vererbungshierarchie angewendet wird, wird nur der Typ mit den meisten Ableitungen verwendet.