Condividi tramite


Configurazione ed estensione del runtime con comportamenti

I comportamenti consentono di modificare il comportamento predefinito e aggiungere estensioni personalizzate che controllano e convalidano la configurazione del servizio o modificano il comportamento di runtime nelle applicazioni client e di servizio di Windows Communication Foundation (WCF). In questo argomento vengono descritte le interfacce di comportamento, come implementarle e come aggiungerle alla descrizione del servizio (in un'applicazione di servizio) o all'endpoint (in un'applicazione client) a livello di codice o in un file di configurazione. Per altre informazioni sull'uso dei comportamenti forniti dal sistema, vedere Specifica del comportamento di Run-Time del servizio e Specifica del comportamento di Run-Time client.

Comportamenti

I tipi di comportamento vengono aggiunti rispettivamente agli oggetti descrizione del servizio o dell'endpoint di servizio (rispettivamente nel servizio o nel client) prima che tali oggetti vengano usati da Windows Communication Foundation (WCF) per creare un runtime che esegue un servizio WCF o un client WCF. Quando questi comportamenti vengono chiamati durante il processo di costruzione del runtime, possono accedere alle proprietà e ai metodi di runtime che modificano il runtime costruito dal contratto, dalle associazioni e dagli indirizzi.

Metodi di comportamento

Tutti i comportamenti hanno un AddBindingParameters metodo, un ApplyDispatchBehavior metodo, un Validate metodo e un ApplyClientBehavior metodo con un'unica eccezione: poiché IServiceBehavior non è possibile eseguire in un client, non implementa ApplyClientBehavior.

  • Utilizzare il metodo AddBindingParameters per modificare o aggiungere oggetti personalizzati a una raccolta a cui le associazioni personalizzate possono accedere per il loro utilizzo quando viene costruito il runtime. Ad esempio, questo è il modo in cui vengono specificati i requisiti di protezione che influiscono su come viene costruito il canale, ma lo sviluppatore del canale non li conosce.

  • Usare il Validate metodo per esaminare l'albero delle descrizioni e l'oggetto runtime corrispondente per assicurarsi che sia conforme a un set di criteri.

  • Usare i metodi ApplyDispatchBehavior e ApplyClientBehavior per esaminare l'albero delle descrizioni e modificare il runtime per un particolare ambito sia sul servizio che sul client. È anche possibile inserire oggetti di estensione.

    Annotazioni

    Anche se in questi metodi viene fornito un albero di descrizione, è solo per l'esame. Se viene modificato un albero della descrizione, il comportamento non è definito.

Le proprietà che è possibile modificare e le interfacce di personalizzazione che è possibile implementare sono accessibili tramite le classi di runtime del servizio e del client. I tipi di servizio sono le DispatchRuntime classi e DispatchOperation . I tipi client sono le classi ClientRuntime e ClientOperation. Le classi ClientRuntime e DispatchRuntime sono i punti di ingresso di estendibilità per accedere alle proprietà di runtime a livello di client e a livello di servizio e alle raccolte di estensioni, rispettivamente. Analogamente, le classi ClientOperation e DispatchOperation espongono rispettivamente le proprietà del runtime dell'operazione client e le raccolte di estensioni dell'operazione del servizio. È tuttavia possibile accedere all'oggetto runtime con ambito più ampio dall'oggetto runtime dell'operazione e viceversa, se necessario.

Annotazioni

Per una descrizione delle proprietà di runtime e dei tipi di estensione che è possibile usare per modificare il comportamento di esecuzione di un client, vedere Estensione dei client. Per una descrizione delle proprietà di runtime e dei tipi di estensione che è possibile usare per modificare il comportamento di esecuzione di un dispatcher del servizio, vedere Estensione dei dispatcher.

La maggior parte degli utenti WCF non interagisce direttamente con il runtime; Usano invece costrutti del modello di programmazione di base come endpoint, contratti, associazioni, indirizzi e attributi di comportamento per classi o comportamenti nei file di configurazione. Questi costrutti costituiscono l'albero delle descrizioni, ovvero la specifica completa per la costruzione di un runtime per supportare un servizio o un client descritto dall'albero della descrizione.

Esistono quattro tipi di comportamenti in WCF:

È possibile aggiungere questi comportamenti ai vari oggetti description implementando attributi personalizzati, usando i file di configurazione dell'applicazione o direttamente aggiungendoli all'insieme behaviors nell'oggetto description appropriato. È tuttavia necessario aggiungere l'oggetto a una descrizione del servizio o a una descrizione dell'endpoint di servizio prima di chiamare ICommunicationObject.Open su ServiceHost o su ChannelFactory<TChannel>.

Ambiti di comportamento

Esistono quattro tipi di comportamento, ognuno dei quali corrisponde a un particolare ambito di accesso in fase di esecuzione.

Comportamenti del servizio

I comportamenti del servizio, che implementano IServiceBehavior, sono il meccanismo principale in base al quale si modifica l'intero runtime del servizio. Esistono tre meccanismi per l'aggiunta di comportamenti del servizio a un servizio.

  1. Uso di un attributo nella classe del servizio. Quando un oggetto ServiceHost viene costruito, l'implementazione usa la ServiceHost reflection per individuare il set di attributi sul tipo di servizio. Se uno di questi attributi sono implementazioni di IServiceBehavior, vengono aggiunti alla raccolta di comportamenti in ServiceDescription. In questo modo questi comportamenti possono partecipare alla costruzione del runtime del servizio.

  2. Aggiungere a livello programmatico i comportamenti alla raccolta di comportamenti su ServiceDescription. Questa operazione può essere eseguita con le righe di codice seguenti:

    ServiceHost host = new ServiceHost(/* Parameters */);
    host.Description.Behaviors.Add(/* Service Behavior */);
    
  3. Implementazione di un oggetto personalizzato BehaviorExtensionElement che estende la configurazione. Ciò consente l'uso del comportamento del servizio dai file di configurazione dell'applicazione.

Esempi di comportamenti del servizio in WCF includono l'attributo ServiceBehaviorAttribute, il comportamento ServiceThrottlingBehavior, e il comportamento ServiceMetadataBehavior.

Comportamenti del contratto

I comportamenti del contratto, che implementano l'interfaccia IContractBehavior, vengono utilizzati per estendere il runtime sia del client che del servizio attraverso un contratto.

Esistono due meccanismi per aggiungere comportamenti a un contratto. Il primo meccanismo consiste nel creare un attributo personalizzato da usare nell'interfaccia del contratto. Quando un'interfaccia del contratto viene passata a ServiceHost o a ChannelFactory<TChannel>, WCF esamina gli attributi dell'interfaccia. Se sono implementazioni di IContractBehavior, gli attributi vengono aggiunti alla raccolta di comportamenti nell'oggetto System.ServiceModel.Description.ContractDescription creato per tale interfaccia.

È anche possibile implementare nell'attributo System.ServiceModel.Description.IContractBehaviorAttribute comportamento del contratto personalizzato. In questo caso, il comportamento è il seguente quando applicato a:

•Interfaccia del contratto. In questo caso, il comportamento viene applicato a tutti i contratti di quel tipo in qualsiasi endpoint e WCF ignora il valore della IContractBehaviorAttribute.TargetContract proprietà.

•Classe di servizio. In questo caso, il comportamento viene applicato solo agli endpoint il cui contratto corrisponde al valore della proprietà TargetContract.

•Classe di callback. In questo caso, il comportamento viene applicato all'endpoint del client duplex e WCF ignora il valore della TargetContract proprietà .

Il secondo meccanismo consiste nell'aggiungere il comportamento alla raccolta di comportamenti in un oggetto ContractDescription.

Esempi di comportamenti del contratto in WCF includono l'attributo System.ServiceModel.DeliveryRequirementsAttribute . Per altre informazioni e un esempio, vedere l'argomento di riferimento.

Comportamenti degli endpoint

I comportamenti degli endpoint, che implementano IEndpointBehavior, sono il meccanismo principale tramite il quale si modifica l'intero servizio o il runtime client per un endpoint specifico.

Esistono due meccanismi per l'aggiunta di comportamenti degli endpoint a un servizio.

  1. Aggiungere il comportamento alla Behaviors proprietà .

  2. Implementare un oggetto personalizzato BehaviorExtensionElement che estende la configurazione.

Per altre informazioni e un esempio, vedere l'argomento di riferimento.

Comportamenti dell'operazione

I comportamenti di operazione, che implementano l'interfaccia IOperationBehavior, vengono usati per estendere il runtime sia del client che del servizio per ogni operazione.

Esistono due meccanismi per aggiungere comportamenti operativi a un'operazione. Il primo meccanismo consiste nel creare un attributo personalizzato da usare nel metodo che modella l'operazione. Quando un'operazione viene aggiunta a un ServiceHost o a un ChannelFactory, WCF aggiunge tutti gli attributi IOperationBehavior alla raccolta di comportamenti dell'oggetto OperationDescription creato per quell'operazione.

Il secondo meccanismo consiste nell'aggiungere direttamente il comportamento alla raccolta di comportamenti in un oggetto costruito OperationDescription.

Esempi di comportamenti dell'operazione in WCF includono OperationBehaviorAttribute e TransactionFlowAttribute.

Per altre informazioni e un esempio, vedere l'argomento di riferimento.

Uso della configurazione per creare comportamenti

I comportamenti del servizio e dell'endpoint e del contratto possono essere progettati per essere specificati nel codice o usando attributi; solo i comportamenti del servizio e degli endpoint possono essere configurati usando i file di configurazione dell'applicazione o Web. L'esposizione dei comportamenti tramite attributi consente agli sviluppatori di specificare un comportamento in fase di compilazione che non può essere aggiunto, rimosso o modificato in fase di esecuzione. Questo comportamento è spesso adatto per i comportamenti sempre necessari per il corretto funzionamento di un servizio, ad esempio i parametri correlati alla transazione all'attributo System.ServiceModel.ServiceBehaviorAttribute . L'esposizione di comportamenti tramite la configurazione consente agli sviluppatori di lasciare la specifica e la configurazione di tali comportamenti a coloro che distribuiscono il servizio. Questo comportamento è adatto per i comportamenti che sono componenti facoltativi o altre configurazioni specifiche della distribuzione, ad esempio se i metadati vengono esposti per il servizio o la configurazione di autorizzazione specifica per un servizio.

Annotazioni

È anche possibile usare i comportamenti che supportano la configurazione per applicare i criteri dell'applicazione aziendale inserendoli nel file di configurazione machine.config e bloccando tali elementi. Per una descrizione e un esempio, vedere Procedura: Bloccare gli endpoint nell'organizzazione.

Per esporre un comportamento usando la configurazione, uno sviluppatore deve creare una classe derivata di BehaviorExtensionElement e quindi registrare tale estensione con la configurazione.

L'esempio di codice seguente illustra come IEndpointBehavior implementa BehaviorExtensionElement:

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

protected override object CreateBehavior()
{
  return new EndpointBehaviorMessageInspector();
}

Affinché il sistema di configurazione carichi un oggetto personalizzato BehaviorExtensionElement, deve essere registrato come estensione. L'esempio di codice seguente illustra il file di configurazione per il comportamento dell'endpoint precedente:

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

Dove Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector è il tipo di estensione del comportamento e HostApplication è il nome dell'assembly in cui è stata compilata la classe.

Ordine di valutazione

System.ServiceModel.ChannelFactory<TChannel> e System.ServiceModel.ServiceHost sono responsabili della compilazione del runtime dal modello di programmazione e dalla descrizione. I comportamenti, come descritto in precedenza, contribuiscono a tale processo di costruzione nel servizio, nell'endpoint, nel contratto e nelle operazioni.

L'oggetto ServiceHost applica i comportamenti nell'ordine seguente:

  1. Servizio

  2. Contratto

  3. Punto finale

  4. Operazione

All'interno di qualsiasi raccolta di comportamenti, non è garantito alcun ordine.

L'oggetto ChannelFactory<TChannel> applica i comportamenti nell'ordine seguente:

  1. Contratto

  2. Punto finale

  3. Operazione

All'interno di qualsiasi raccolta di comportamenti, anche in questo caso, non è garantito alcun ordine.

Aggiunta di comportamenti a livello di codice

Le proprietà di System.ServiceModel.Description.ServiceDescription nell'applicazione di servizio non devono essere modificate successivamente al CommunicationObject.OnOpening metodo in System.ServiceModel.ServiceHostBase. Alcuni membri, ad esempio la proprietà ServiceHostBase.Credentials e i metodi AddServiceEndpoint su ServiceHostBase e System.ServiceModel.ServiceHost, generano un'eccezione se modificati dopo quel punto. Altri consentono di modificarli, ma il risultato non è definito.

Analogamente, i valori System.ServiceModel.Description.ServiceEndpoint sul client non devono essere modificati dopo la chiamata a OnOpening su System.ServiceModel.ChannelFactory. La ChannelFactory.Credentials proprietà genera un'eccezione se è stata modificata dopo tale punto, ma gli altri valori di descrizione client possono essere modificati senza errori. Il risultato, tuttavia, non è definito.

Sia per il servizio che per il client, è consigliabile modificare la descrizione prima di chiamare CommunicationObject.Open.

Regole di ereditarietà per gli attributi di comportamento

Tutti e quattro i tipi di comportamenti possono essere popolati usando attributi: comportamenti del servizio e comportamenti del contratto. Poiché gli attributi sono definiti su oggetti gestiti e membri e gli oggetti gestiti e i membri supportano l'ereditarietà, è necessario definire il funzionamento degli attributi di comportamento nel contesto dell'ereditarietà.

A livello generale, la regola è che per un particolare ambito (ad esempio, servizio, contratto o operazione), vengono applicati tutti gli attributi di comportamento nella gerarchia di ereditarietà per tale ambito. Se sono presenti due attributi di comportamento dello stesso tipo, viene usato solo il tipo più derivato.

Comportamenti del servizio

Per una determinata classe di servizio, vengono applicati tutti gli attributi del comportamento della prestazione di servizio in quella classe e nei genitori di tale classe. Se lo stesso tipo di attributo viene applicato in più posizioni nella gerarchia di ereditarietà, viene usato il tipo più derivato.

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

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class B : A { /* … */}

Ad esempio, nel caso precedente, il servizio B termina con un InstanceContextMode di Single, una modalità AspNetCompatibilityRequirementsMode di Allowed e una ConcurrencyMode di Single. ConcurrencyMode è Single, perché l'attributo ServiceBehaviorAttribute nel servizio B è più derivato rispetto a quello nel servizio A.

Comportamenti del contratto

Per un determinato contratto, vengono applicati tutti gli attributi di comportamento del contratto su tale interfaccia e sugli elementi padre di tale interfaccia. Se lo stesso tipo di attributo viene applicato in più posizioni nella gerarchia di ereditarietà, viene usato il tipo più derivato.

Comportamenti dell'operazione

Se una determinata operazione non esegue l'override di un'operazione astratta o virtuale esistente, non vengono applicate regole di ereditarietà.

Se un'operazione esegue l'override di un'operazione esistente, vengono applicati tutti gli attributi del comportamento dell'operazione su questa operazione e sui suoi genitori. Se lo stesso tipo di attributo viene applicato in più posizioni nella gerarchia di ereditarietà, viene usato il tipo più derivato.