Pregunta

Tengo un servicio WCF alojado en IIS. La intención es que los clientes hagan una llamada y reciban una clase personalizada que se define en otro proyecto / dll. He generado un cliente de servicio usando el svcutil.exe. El problema es que este cliente autogenerado contiene una nueva definición parcial / proxy para la clase que intento devolver del servicio. Ahora arroja un error de conversión entre mi clase personalizada original y la nueva definición parcial en tiempo de compilación. Entonces, ¿cómo devuelve los tipos definidos por el usuario de un servicio WCF? Consejo apreciado.

¿Fue útil?

Solución

Solo al segundo / de Yossi Pensamientos de Rich:

  • sí, puede agregar una referencia a la dll compartida (en lugar de usar la clase proxy generada)
  • sí, derrota muchas de las intenciones de los contratos de datos, y si está ocurriendo algún tipo de serialización personalizada, puede tener problemas para extender su servicio

He recorrido este camino antes, y de alguna manera desearía no haberlo hecho. Re extensibilidad / serialización personalizada: debe tener mucho cuidado. Un poco más fácil si utiliza un serializador pre-enrollado como protobuf-net ( que puede integrarse directamente en WCF y que está diseñado teniendo en cuenta la extensibilidad), pero no es fácil.

En realidad, una ventaja de compartir las clases es que hace que sea un poco más fácil probar: dado que tiene el mismo IFoo en todas partes, puede burlarse de ese IFoo con posibilidades razonables de éxito. Es más difícil burlarse cuando el proxy se involucra (a medida que cambia más partes móviles entre el código de prueba y el código de producción).

Otros consejos

Si el tipo que desea devolver de su llamada de servicio no está marcado como DataContract , no podrá devolverlo desde WCF sin proporcionar una copia de ese mismo ensamblado a su cliente aplicación.

using System;
using System.ServiceModel;

[ServiceContract]
interface IService
{
    [OperationContract]
    TimeSpan GetTimeSpan();
}

class Service : IService
{
    public TimeSpan GetTimeSpan() { return DateTime.Now.TimeOfDay; }
}

¿Por qué funciona el código anterior entonces? Funciona porque ambos lados de la llamada de servicio tienen System.dll , por lo que ambos conocen el tipo System.TimeSpan , que es el tipo de retorno de OperationContract GetTimeSpan ( ) .

Aquí hay un ejemplo usando un DataContract :

using System;
using System.ServiceModel;
using System.Runtime.Serialization;

[ServiceContract]
interface IService
{
    [OperationContract]
    Contract GetContract();
}

[DataContract]
class Contract
{
    [DataMember]
    public String MyProperty { get; set; }
}

class Service : IService
{
    public Contract GetContract() { return new Contract(); }
}

Ahora ha proporcionado atributos de serialización a una clase que ha definido ( Contract ); esto le permitirá usar svcutil.exe para crear clases proxy en su aplicación cliente eso será serializado y enviado al servicio WCF.

Ahora, si desea devolver un tipo que no sea DataContract , debe proporcionar una copia del ensamblado que contiene ese tipo a su aplicación cliente.

Una de las cosas que tendrá que suceder es que el usuario debe configurar la referencia de servicio para usar sus tipos desde la DLL en lugar de la clase definida por el proxy - http://msdn.microsoft.com/en-us/library/bb628653.aspx

Hemos recorrido ese camino en el pasado, y de hecho el problema es que, por supuesto, estas son dos clases diferentes, por lo que deberá seguir el enlace proporcionado por @Rich Reuter;

Sin embargo, hemos aprendido de la manera difícil por qué esto es una mala práctica, ya que va en contra del tercer principio del SOA- "Esquema y contrato de servicios compartidos, no de clase".

Por supuesto, el problema no es simplemente no seguir una " regla " establecido por alguien en algún momento, pero que había grandes razones para sugerir esto: hemos aprendido que el precio de un acoplamiento tan estrecho entre el servicio y el cliente significa que es muy difícil liberarlo, si el servicio necesita agregar otro campo para esa clase, para atender a otro cliente: el primer cliente podría verse afectado; si el servicio necesita cambiar algo en esa definición de clase (para atender a otro cliente), el primer cliente se verá afectado nuevamente y viceversa, el cliente puede afectar el ciclo de vida del servicio.

En proyectos grandes esto rápidamente se convierte en una gran carga de mantenimiento.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top