2010-02-19 19 views
9

Tengo un servicio web WCF que tiene un método que devuelve una colección genérica. Ahora, mi pregunta es: ¿debo exponerlo como ICollection<T>, List<T>, IList<T>, IEnumerable<T> o algo más?WCF OperationContract: ¿qué tipo de colección genérica debo exponer?

Supongo que List<T> está fuera de lugar ya que quiero evitar CA1002 errors, pero el tipo subyacente será List<T>.

Estoy realmente interesado en escuchar sus opiniones sobre esto, de preferencia con una buena explicación de por qué piensa lo que piensa.

Gracias de antemano

Respuesta

16

Tenga en cuenta que los errores tales como CA1002 realmente están destinados a aplicarse a bibliotecas. Un servicio WCF no es una biblioteca, es un punto final que está todo sobre la serialización SOAP, REST, etc.

Usted encontrará que si se intenta exponer una interfaz como ICollection<T> o IList<T>, obtendrá errores que las tipo no puede ser serializado. De hecho, List<T> es probablemente la mejor opción aquí. Cuando se genera un proxy en el lado del cliente, termina como una matriz de forma predeterminada, y muchos, si no la mayoría, lo cambian a List<T>, por lo que el 90% de las veces, independientemente de cómo elija exponerlo, ese es el tipo que el cliente va a ver de todos modos.

Notaré que generalmente es una buena práctica no "devolver" una colección de una operación WCF o un servicio web en general. Es más común para crear una clase de proxy que contiene la colección que desea, y devolver eso, es decir:

[OperationContract] 
OrdersResult GetOrders(OrderRequest request); 

Cuando la clase de proxy podría tener este aspecto:

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

De esa manera si usted decide Necesita agregar más datos a la solicitud o la respuesta, puede hacerlo sin causar cambios bruscos en el cliente.


Adición: El verdadero problema aquí es que con WCF WCF no sabe que un tipo particular sólo se utiliza para los datos salientes. Cuando cualquier clase se expone a través de un servicio WCF, WCF supone que puede ser parte de cualquiera de una solicitud o una respuesta , y si es parte de una solicitud, entonces el tipo debe ser concreta y no puede ser inmutable. Esa es la razón de todas las otras restricciones tontas como exigir el establecimiento de propiedades.

Simplemente no tiene otra opción más que usar un tipo de colección concreta y mutable, y en la mayoría de los casos eso significa una matriz o una lista genérica.

6

En mi opinión, los contratos de servicios y datos que exponen secuencias debe señalar claramente que esas secuencias son inmutables , ya que están viajando a través del cable como dtos. No tiene mucho sentido agregar y eliminar en una secuencia que recibió de un nivel diferente. Más bien, quiere leer esa información y hacer algo con ella.

Dado que, realmente preferiría usar IEnumerable<T>, pero desafortunadamente, esto simplemente no funciona bien con WCF. Puede obtener todo tipo de errores extraños, especialmente cuando se trata de ejecución diferida, por lo que (en un contexto de WCF) es mejor mantenerse alejado de ellos.

Eso realmente solo deja matrices, ya que comunican el mejor intento de las opciones restantes.

+0

De acuerdo con la parte sobre la inmutabilidad, aunque las matrices no son realmente más inmutables que las listas genéricas; solo el * tamaño * es inmutable. – Aaronaught

+1

Sí, lo sé, por eso habría preferido IEnumerable, pero dado que no es una opción, tenemos que conformarnos con el siguiente mejor. Las matrices son todavía "más inmutables" que las Listas porque no se puede cambiar el tamaño, por lo que comunican la intención un poco más claramente ... pero no por mucho, concedo :) –

+1

Lol "más inmutable". Supongo que es una buena explicación como cualquiera. :PAG – Aaronaught

Cuestiones relacionadas