2009-11-08 15 views
79

Basta chiedersi in quali circostanze preferiresti generare un proxy da un servizio WCF quando puoi semplicemente richiamare le chiamate utilizzando ChannelFactory?WCF ChannelFactory vs proxy di generazione

In questo modo non sarà necessario generare un proxy e preoccuparsi di rigenerare un proxy quando il server viene aggiornato?

Grazie

risposta

82

Ci sono 3 modi di base per creare un client WCF:

  1. Let Visual Studio generare il proxy. Questo auto genera codice che si collega al servizio leggendo il WSDL. Se il servizio cambia per qualsiasi motivo, devi rigenerarlo. Il grande vantaggio di questo è che è facile da configurare: VS ha un wizard ed è tutto automatico. Lo svantaggio è che ti affidi a VS per fare tutto il lavoro duro per te, e così perdi il controllo.

  2. Utilizzare ChannelFactory con un'interfaccia nota. Questo dipende dal fatto che tu abbia interfacce locali che descrivono il servizio (il contratto di servizio). Il grande vantaggio è che può gestire le modifiche molto più facilmente - è ancora necessario ricompilare e correggere le modifiche, ma ora non si sta rigenerando il codice, si fa riferimento alle nuove interfacce. Comunemente questo viene usato quando si controllano sia server che client in quanto entrambi possono essere più facilmente derisi per il test dell'unità. Tuttavia, le interfacce possono essere scritte per qualsiasi servizio, anche quelle REST - dai uno sguardo allo this Twitter API.

  3. Scrivi il proprio proxy - questo è abbastanza facile da fare, specialmente per i servizi REST, utilizzando lo HttpClient o WebClient. Questo ti dà il controllo dei grani più fine, ma al costo di molte API di servizi che si trovano nelle stringhe. Ad esempio: var content = new HttpClient().Get("http://yoursite.com/resource/id").Content; - se i dettagli dell'API cambiano, non si verificherà un errore fino al runtime.

opzione 1 Personalmente mi è mai piaciuto - basandosi sulla generato automaticamente il codice è disordinato e perde troppo controllo. Inoltre, spesso crea problemi di serializzazione - finisco con due classi identiche (una nel codice del server, una generata automaticamente) che può essere controllata ma è un problema.

L'opzione 2 dovrebbe essere perfetta, ma i canali sono un po 'troppo limitanti, ad esempio completely lose the content of HTTP errors. Detto questo, avere interfacce che descrivono il servizio è molto più facile da codificare e gestire.

+2

@MurHaf No: questa risposta è interamente opera mia. Attribuisco SEMPRE i contributi degli altri. Ho scritto questa risposta sulla base di anni di lavoro con i servizi SOAP in .Net in vari lavori. L'articolo a cui ti colleghi è del marzo 2013, mentre la mia risposta è stata scritta nell'aprile 2010 - 3 anni prima! Se si è verificato un plagio, mi ha copiato. Dovresti controllare le date prima di fare accuse in quanto è molto facile da fare. – Keith

+0

@MurHaf non arriviamo nemmeno alle stesse conclusioni: quell'articolo consiglia di generare automaticamente un proxy (opzione 1) come "semplice". Lo descrivo come facile da configurare, ma disordinato e difficile da mantenere. Non parla nemmeno di scrivere il tuo proxy (opzione 3). – Keith

+1

Penso che anche SvcUtil dovrebbe essere menzionato, in quanto questo è uno dei modi più comuni per "scrivere" un client. –

11

bene al fine di utilizzare ChannelFactory<T> si deve essere disposti a condividere le assemblee dei contratti tra il servizio e il cliente. Se questo è okay, allora lo ChannelFactory<T> può farti risparmiare tempo.

+2

Questo non è proprio vero. –

+0

@Charles - puoi spiegare perché questo non è vero? –

+5

@Aran: Penso che quello che Andrew intende dire sia corretto - che se non vuoi generare facsimili delle classi di contratto, allora avresti bisogno di avere accesso agli originali. È vero che in un modo o nell'altro è necessario avere quelle classi di contratto. Puoi generarli, scriverli a mano o ottenere il codice sorgente del servizio (se è nella stessa lingua). Condividere gli assembly è il modo più semplice, ma non è sempre possibile. (Forse sto prendendo anche Andrew troppo alla lettera, ma qui la chiarezza è importante.) –

8

Il proxy creerà le funzioni asincrone per le quali è gentile.

+2

sì - allo stesso tempo, sia "Aggiungi riferimento al servizio" di Visual Studio che svcutil.exe sulla riga di comando macellano la configurazione oltre il riconoscimento .... almeno con svcutil.exe, puoi definire un "/ noconfig" switch ..... –

+1

ChannelFactory fornisce anche metodi asincroni: http://msdn.microsoft.com/en-us/library/ms731177.aspx Ma preferisco usare un modello T4 per creare una classe asincrona usando ThreadPool che invocare metodi sincroni. – SandRock

+0

Che cos'è un modello T4? – TheWommies

20

Uso ChannelFactory insieme al metodo MetadataResolver.Resolve. La configurazione del client è un problema, quindi ottengo il mio ServiceEndpoint dal server.

Quando si utilizza ChannelFactory (Of T), T è il contratto originale che è possibile ottenere da un riferimento nel progetto o da un'istanza del contratto generata. In alcuni progetti, ho generato il codice da un riferimento di servizio perché non è stato possibile aggiungere un riferimento alla dll del contratto. È anche possibile generare un contratto asynch con il riferimento del servizio e utilizzare l'interfaccia del contratto con ChannelFactory.

Il punto principale dell'utilizzo di ChannelFactory per me è stato quello di eliminare le informazioni di configurazione del client WCF.Nel seguente codice di esempio, è possibile vedere come ottenere un client WCF senza configurazione.

Dim fixedAddress = "net.tcp://server/service.svc/mex" 
Dim availableBindings = MetadataResolver.Resolve(GetType(ContractAssembly.IContractName), New EndpointAddress(fixedAddress)) 
factoryService = New ChannelFactory(Of ContractAssembly.IContractName)(availableBindings(0)) 
accesService = factoryService.CreateChannel() 

Nel mio progetto finale, i availableBindings sono controllati da usare net.tcp o net.pipe se disponibile. In questo modo, posso utilizzare la migliore associazione disponibile per le mie esigenze. Mi baso solo sul fatto che sul server esiste un endpoint di metadati.

Spero che questo aiuta

BTW, questo viene fatto utilizzando .NET 3.5. Tuttavia funziona anche con 4.0.

+0

Cose fantastiche. Io uso MetadataResolver.Resolve pure per la configurazione ma non ho pensato di risolvere il binding dal server. Ottimo punto! –

+0

upvote per aver menzionato "Il punto principale dell'uso di ChannelFactory per eliminare la configurazione del client WCF" – Kurubaran

7

La mia risposta è una sorta di riassunto delle risposte Keith's e Andrew Hare's.

Se non si controlla il server, ma solo WSDL/URL- generare il proxy utilizzando Visual Studio o svcutil. (Si noti che Visual Studio a volte fallisce, quando svcutil funziona meglio).

Quando si controllano sia server che client, condividere interfacce/contratti e chiamare ChannelFactory
.

2

Non è solo una questione di tempo risparmiato. L'utilizzo del proxy generato da WSDL è pericoloso perché se si dimentica di aggiornare il riferimento del servizio è possibile lasciare la soluzione in uno stato incoerente. Tutto si compila ma il contratto di servizio è rotto. Suggerisco sicuramente di usare ChannelFactory ogni volta che è possibile, rendete la vostra vita molto più semplice.

Una possibile alternativa potrebbe essere quella di scrivere uno script di pre-installazione che richiami l'utility SVCUtil per creare il proxy ogni volta che si crea il progetto, ma ChannelFactory è molto più pulito ed elegante.

Problemi correlati