2010-02-19 11 views
9

Ho un servizio Web WCF che ha un metodo che restituisce una raccolta generica. Ora, la mia domanda è: dovrei esporlo come ICollection<T>, List<T>, IList<T>, IEnumerable<T> o qualcos'altro?WCF OperationContract - quale tipo di raccolta generico dovrei esporre?

Suppongo che List<T> sia fuori questione dal momento che voglio evitare CA1002 errors, ma il tipo sottostante sarà un List<T>.

Sono davvero interessato a sentire le tue osservazioni su questo, preferibilmente con una buona spiegazione del perché pensi ciò che pensi.

Grazie in anticipo

risposta

16

Tenete a mente che gli errori, come CA1002 devono realmente valido per le librerie. Un servizio WCF non è una libreria, è un punto finale che è la serializzazione tutto sopra SOAP, REST, ecc

Troverete che se si tenta di esporre un'interfaccia come ICollection<T> o IList<T>, si otterrà gli errori che le il tipo non può essere serializzato. Infatti, List<T> è probabilmente la scelta migliore qui. Quando un proxy viene generato sul lato client, finisce come array per impostazione predefinita e molti, se non la maggior parte delle persone, lo cambia in un List<T>, quindi il 90% delle volte, indipendentemente dal modo in cui si sceglie di esporlo, questo è il tipo che il cliente vedrà comunque.

Noterò che è generalmente buona norma non "restituire" una raccolta affatto da un'operazione WCF o da un servizio Web in generale. E 'più comune per creare una classe proxy che contiene la raccolta che si desidera, e restituire quello, vale a dire:

[OperationContract] 
OrdersResult GetOrders(OrderRequest request); 

Dove la classe proxy potrebbe essere simile a questo:

[DataContract] 
public class OrdersResult 
{ 
    [DataMember] 
    public List<Order> Orders { get; set; } 
} 

In questo modo se si decide è necessario aggiungere più dati alla richiesta o alla risposta, è possibile farlo senza causare interruzioni delle modifiche al client.


Addendum: Il vero problema qui con WCF è che WCF non sa che un particolare tipo è utilizzato solo per i dati in uscita. Quando una classe viene esposto attraverso un servizio WCF WCF suppone che può essere parte di una richiesta o un risposta, e se è parte di una richiesta, quindi il tipo devono essere concreti e non può essere immutabile. Questa è la ragione per tutte le altre sciocche restrizioni come la richiesta di setter di proprietà.

Semplicemente non avete altra scelta qui se non usare un tipo di raccolta concreta e mutevole e nella maggior parte dei casi significa un array o un elenco generico.

6

a mio parere, di servizio e di dati dei contratti che espongono le sequenze dovrebbe segnalare chiaramente che i sequenze sono immutabili, dal momento che sono in viaggio oltre il filo come DTOs. Non ha molto senso aggiungere e rimuovere una sequenza ricevuta da un livello diverso. Piuttosto, vuoi leggere quei dati e fare qualcosa con esso.

Dato che, io preferirei davvero utilizzare IEnumerable<T>, ma sfortunatamente, questo non funziona bene con WCF. È possibile ottenere tutti i tipi di errori strani, in particolare quando si tratta di esecuzione differita, quindi (in un contesto WCF) è meglio stare lontano da quelli.

Questo lascia solo gli array , poiché comunicano l'intento migliore delle restanti opzioni.

+0

Accetto con la parte relativa all'immutabilità, sebbene gli array non siano davvero più immutabili di quelli generici; solo la * dimensione * è immutabile. – Aaronaught

+1

Sì, lo so, ed è per questo che avrei preferito IEnumerable, ma dato che questa non è un'opzione, dobbiamo accontentarci del prossimo migliore. Gli array sono ancora "più immutabili" di Lists perché non è possibile modificare le dimensioni, quindi comunicano l'intento un po 'più chiaramente ... ma non di molto, concedo :) –

+1

Lol "più immutabile". Immagino sia una buona spiegazione come qualsiasi. : P – Aaronaught