Estensione di dispatcher
Il livello del modello di servizi è responsabile dell'estrazione dei messaggi in arrivo dai canali sottostanti, della loro conversione in chiamate al metodo nel codice dell'applicazione e della restituzione dei risultati al chiamante. Le estensioni del modello di servizi modificano o implementano il comportamento e le funzioni dell'esecuzione o della comunicazione relativamente a funzionalità del client o del dispatcher, comportamenti personalizzati, intercettazione di messaggi e parametri e altre funzionalità di estendibilità.
In questo argomento viene illustrato come utilizzare le classi DispatchRuntime e DispatchOperation in un'applicazione di servizio Windows Communication Foundation (WCF) per modificare il comportamento di esecuzione predefinito di un dispatcher o per intercettare o modificare messaggi, parametri o valori restituiti prima o dopo il loro invio o recupero dal livello del canale. Per ulteriori informazioni sull'elaborazione equivalente dei messaggi runtime del client, vedere Estensione dei client. Per comprendere il ruolo dei tipi IExtensibleObject nell'accesso allo stato condiviso tra vari oggetti di personalizzazione runtime, vedere Oggetti estensibili.
Dispatcher
Il livello del modello di servizi esegue la conversione tra il modello di programmazione dello sviluppatore e lo scambio di messaggi sottostante, comunemente denominato livello del canale. In WCF, i dispatcher di canale ed endpoint (rispettivamente ChannelDispatcher e EndpointDispatcher) sono i componenti del servizio responsabili dell'accettazione di nuovi canali, della ricezione di messaggi, della chiamata e dell'invio di operazioni e dell'elaborazione delle risposte. Gli oggetti dispatcher sono oggetti destinatario, ma anche le implementazioni del contratto di callback nei servizi duplex espongono oggetti dispatcher per ispezione, modifica o estensione.
Il dispatcher del canale (e la classe IChannelListener complementare) estrae i messaggi dal canale sottostante e li passa ai rispettivi dispatcher dell'endpoint. Ogni dispatcher dell'endpoint ha una classe DispatchRuntime che indirizza i messaggi alla classe DispatchOperation appropriata, responsabile della chiamata al metodo che implementa l'operazione. Durante il processo vengono richiamate e coinvolte varie classi di estensione facoltative e obbligatorie. In questo argomento viene illustrato come vengono assemblati questi pezzi e come è possibile modificare proprietà e inserirvi il proprio codice per estendere la funzionalità di base.
Le proprietà dispatcher e gli oggetti di personalizzazione modificati vengono inseriti utilizzando oggetti comportamento di servizi, endpoint, contratti o operazioni. In questo argomento non viene descritto come utilizzare i comportamenti. Per ulteriori informazioni sui tipi utilizzati per inserire modifiche dei dispatcher, vedere Procedura: bloccare gli endpoint nell'organizzazione.
Nel grafico seguente viene fornita una panoramica dettagliata degli elementi architettonici di un servizio.
Dispatcher del canale
Viene creato un oggetto ChannelDispatcher per associare una classe IChannelListener in un particolare URI (denominato URI di ascolto) a un'istanza di un servizio. Ogni oggetto ServiceHost può quindi avere numerosi oggetti ChannelDispatcher, ognuno associato a un solo listener e URI di ascolto. All'arrivo di un messaggio ChannelDispatcher esegue una query su ognuno degli oggetti EndpointDispatcher associati per scoprire se l'endpoint può accettare il messaggio, quindi passa il messaggio all'endpoint che ne ha la possibilità.
Tutte le proprietà che controllano la durata e il comportamento di una sessione del canale sono disponibili per essere controllate o modificate sull'oggetto ChannelDispatcher. Sono inclusi gli inizializzatori di canale personalizzati, il listener del canale, l'host, l'oggetto InstanceContexte associato e così via.
Dispatcher dell'endpoint
L'oggetto EndpointDispatcher è responsabile dell'elaborazione dei messaggi da una classe ChannelDispatcher, quando l'indirizzo di destinazione di un messaggio corrisponde alla proprietà AddressFilter e l'azione del messaggio corrisponde alla proprietà ContractFilter. Se due oggetti EndpointDispatcher possono accettare un messaggio, il valore della proprietà FilterPriority determina l'endpoint con la priorità più elevata.
Utilizzare EndpointDispatcher per acquisire i due principali punti di estensione del modello di servizi, ovvero le classi DispatchRuntime e DispatchOperation, utilizzabili per personalizzare l'elaborazione del dispatcher. La classe DispatchRuntime consente agli utenti di intercettare ed estendere il dispatcher nell'ambito del contratto, ovvero per tutti i messaggi del contratto. La classe DispatchOperation consente agli utenti di intercettare ed estendere il dispatcher nell'ambito di un'operazione, ovvero per tutti i messaggi in un'operazione.
Scenari
Esistono vari motivi per estendere il dispatcher:
Convalida di messaggi personalizzata. Gli utenti possono imporre che un messaggio sia valido per un certo schema. A questo scopo, è possibile implementare le interfacce degli intercettori di messaggi. Per un esempio, vedere Message Inspectors.
Registrazione di messaggi personalizzata. Gli utenti possono controllare e registrare un insieme di messaggi dell'applicazione che passano attraverso un endpoint. Questa operazione può essere eseguita anche con le interfacce degli intercettori di messaggi.
Trasformazioni di messaggi personalizzate. Gli utenti possono applicare determinate trasformazioni al messaggio nel runtime (ad esempio per il controllo delle versioni). Anche in questo caso, l'operazione può essere eseguita con le interfacce degli intercettori di messaggi.
Modello di dati personalizzato. Gli utenti possono disporre di un modello di serializzazione dei dati diverso da quelli supportati per impostazione predefinita in WCF (ovvero oggetti System.Runtime.Serialization.DataContractSerializer, System.Xml.Serialization.XmlSerializer e messaggi non elaborati). A questo scopo, è possibile implementare le interfacce dei formattatori di messaggi. Per un esempio, vedere Operation Formatter And Operation Selector.
Convalida di parametri personalizzata. Gli utenti possono imporre che i parametri tipizzati siano validi (a differenza di XML). A questo scopo, è possibile utilizzare le interfacce di controllo dei parametri. Per un esempio, vedere Parameter Filter.
Invio di operazioni personalizzato. Gli utenti possono implementare l'invio su un elemento diverso dall'azione, ad esempio, sull'elemento corpo o su una proprietà del messaggio personalizzata. A questo scopo, utilizzare l'interfaccia IDispatchOperationSelector. Per un esempio, vedere Operation Formatter And Operation Selector.
Pool di oggetti. Gli utenti possono eseguire il pool delle istanze invece di allocare una nuova istanza per ogni chiamata. A questo scopo, utilizzare le interfacce del provider di istanze. Per un esempio, vedere Pooling.
Leasing di istanza. Gli utenti possono implementare un modello di leasing per la durata dell'istanza, simile a quello di .NET Framework Remoting. A questo scopo, è possibile utilizzare le interfacce di durata del contesto dell'istanza.
Gestione degli errori personalizzata. Gli utenti possono controllare come vengono elaborati gli errori locali e come vengono comunicati ai client. A questo scopo, utilizzare le interfacce IErrorHandler.
Comportamenti di autorizzazione personalizzati. Gli utenti possono implementare il controllo di accesso personalizzato estendendo i pezzi di runtime Contratto o Operazione e aggiungendo controlli di protezione basati sui token presenti nel messaggio. L'operazione può essere eseguita con le interfacce degli intercettori di messaggi o di parametri. Per alcuni esempi, vedere Security Extensibility Samples.
Attenzione: Poiché la modifica di proprietà di protezione può compromettere la protezione delle applicazioni WCF, è consigliabile intraprendere modifiche relative alla protezione con attenzione e testarle accuratamente prima della distribuzione. Convalide del runtime WCF personalizzate. È possibile installare convalide personalizzate che esaminano servizi, contratti e associazioni, per imporre criteri a livello di azienda in relazione ad applicazioni WCF. Per un esempio, vedere Procedura: bloccare gli endpoint nell'organizzazione.
Utilizzo della classe DispatchRuntime
Utilizzare la classe DispatchRuntime per modificare il comportamento predefinito di un servizio o di un singolo endpoint oppure per inserire oggetti che implementano modifiche personalizzate in uno o entrambi i processi del servizio (o i processi client nel caso di un client duplex) seguenti:
- Trasformazione di messaggi in arrivo in oggetti e rilascio di tali oggetti come chiamate al metodo su un oggetto servizio.
- Trasformazione di oggetti ricevuti dalla risposta a una chiamata a operazioni del servizio in messaggi in uscita.
DispatchRuntime consente di intercettare ed estendere il dispatcher del canale o dell'endpoint per tutti i messaggi di un particolare contratto, anche quando un messaggio non viene riconosciuto. Quando arriva un messaggio che non corrisponde ad alcun messaggio dichiarato nel contratto, viene inviato all'operazione restituita dalla proprietà UnhandledDispatchOperation. Per l'intercettazione o l'estensione in tutti i messaggi relativi a una particolare operazione, vedere la classe DispatchOperation.
Sono presenti quattro aree principali di estendibilità del dispatcher esposto dalla classe DispatchRuntime:
- I componenti del canale utilizzano le proprietà di DispatchRuntime e quelle del dispatcher del canale associato, restituito dalla proprietà ChannelDispatcher, per personalizzare la modalità utilizzata dal dispatcher del canale per accettare e chiudere canali. In questa categoria sono incluse le proprietà ChannelInitializers e InputSessionShutdownHandlers.
- I componenti dei messaggi vengono personalizzati per ogni messaggio elaborato. In questa categoria sono incluse le proprietà MessageInspectors, OperationSelector, Operations e ErrorHandlers.
- I componenti dell'istanza personalizzano la creazione, la durata e l'eliminazione di istanze del tipo di servizio. Per ulteriori informazioni sulle durate degli oggetti di servizio, vedere la proprietà InstanceContextMode. In questa categoria sono incluse le proprietà InstanceContextInitializers e InstanceProvider.
- I componenti correlati alla protezione possono utilizzare le proprietà seguenti:
- SecurityAuditLogLocation indica dove vengono scritti gli eventi di controllo.
- ImpersonateCallerForAllOperations controlla se il servizio tenta di eseguire una rappresentazione utilizzando le credenziali fornite dal messaggio in ingresso.
- MessageAuthenticationAuditLevel controlla se nel registro eventi specificato da SecurityAuditLogLocation vengono scritti eventi di autenticazione dei messaggi riusciti.
- PrincipalPermissionMode controlla le modalità di impostazione della proprietà CurrentPrincipal.
- ServiceAuthorizationAuditLevelspecifica le modalità di esecuzione del controllo degli eventi di autorizzazione.
- SuppressAuditFailure specifica se sopprimere le eccezioni non critiche che si verificano durante il processo di registrazione.
In genere, gli oggetti di estensione personalizzati vengono assegnati a una proprietà DispatchRuntime o inseriti in un insieme da un comportamento del servizio (un oggetto che implementa IServiceBehavior), un comportamento del contratto (un oggetto che implementa IContractBehavior) o un comportamento dell'endpoint (un oggetto che implementa IEndpointBehavior). L'oggetto del comportamento da installare viene quindi aggiunto all'insieme appropriato di comportamenti a livello di programmazione o implementando un oggetto BehaviorExtensionElement personalizzato per consentire l'inserimento del comportamento utilizzando un file di configurazione dell'applicazione.
I client duplex (client che implementano un contratto di callback specificato da un servizio duplex) hanno anche un oggetto DispatchRuntime a cui è possibile accedere utilizzando la proprietà CallbackDispatchRuntime.
Utilizzo della classe DispatchOperation
La classe DispatchOperation è il luogo in cui è possibile eseguire modifiche del runtime ed è il punto di inserimento per estensioni personalizzate nell'ambito di una sola operazione del servizio. Per modificare il comportamento del runtime del servizio per tutti i messaggi di un contratto, utilizzare la classe DispatchRuntime.
Installare modifiche di DispatchOperation utilizzando un oggetto comportamento del servizio personalizzato.
Utilizzare la proprietà Operations per individuare l'oggetto DispatchOperation che rappresenta un'operazione specifica del servizio.
Le proprietà seguenti controllano l'esecuzione del runtime a livello di operazione:
- Le proprietà Action, ReplyAction, FaultContractInfos, IsOneWay, IsTerminating e Name ottengono i rispettivi valori dell'operazione.
- TransactionAutoComplete e TransactionRequired specificano il comportamento della transazione.
- Le proprietà ReleaseInstanceBeforeCall e ReleaseInstanceAfterCall controllano la durata dell'oggetto di servizio definito dall'utente relativo alla classe InstanceContext.
- Le proprietà DeserializeRequest, SerializeReply e Formatter consentono di controllare esplicitamente la conversione dei messaggi in oggetti e viceversa.
- La proprietà Impersonation specifica il livello di rappresentazione dell'operazione.
- La proprietà CallContextInitializers inserisce estensioni del contesto di chiamata personalizzate per l'operazione.
- La proprietà AutoDisposeParameters controlla quando vengono eliminati in modo permanente gli oggetti parametro.
- La proprietà Invoker consente di inserire un oggetto invoker personalizzato.
- La proprietà ParameterInspectors consente di inserire un controllo del parametro personalizzato utilizzabile per controllare o modificare parametri e valori restituiti.
Vedere anche
Attività
Procedura: ispezionare e modificare i messaggi sul servizio
Procedura: controllare o modificare i parametri
Procedura: bloccare gli endpoint nell'organizzazione