2010-06-25 11 views
36

Mi primera pregunta para que la esperanza es adecuado:WCF Servicio de Referencia genera su propia interfaz de contrato, no va a volver a utilizar las minas

conjunto de la interfaz compartida - en los que he un montaje 'compartida' que tiene una interfaz, dejar que la llamada es IDocRepository. Está marcado con [ServiceContract] y hay varios métodos con [OperationContract].

Conjuntos de implementación WCF - Tengo dos proyectos de servicio WCF, cada uno haciendo referencia al ensamblado compartido, cada uno implementando esa interfaz como un servicio WCF.

Ensamblaje para el consumidor - Finalmente, tengo un proyecto de 'cliente', que también hace referencia al ensamblado compartido, con una referencia a cada uno de los dos servicios de WCF.

Sin embargo, las referencias de servicios generados en el montaje de los consumidores se derivan de una versión generada automáticamente de la interfaz:

public partial class ExampleClient : System.ServiceModel.ClientBase<SomeNamespace.ExampleSvcRef.IDocRepository>, SomeNamespace.ExampleSvcRef.IDocRepository { 

Lo que esperaba
yo habría esperado que ambas referencias que, en cambio heredará automáticamente la interfaz que definí, que el ensamblaje consumidor/cliente también hace referencia. Algo así como la reutilización de las clases que proporciona para los tipos de parámetros y de retorno, pero para la interfaz de servicio.

Por qué
De modo que pueda crear una instancia del proxy de referencia, bien servicio y echarlo a mi tipo de interfaz.

Entonces, ¿podría modificar el código generado a mano cada vez, pero debería haber una mejor manera ...?

(edit: Tengo 'tipos reutilización en ensamblados de referencia' y 'tipos reutilización en todos los ensamblados de referencia' opciones seleccionadas para ambas referencias de servicio)

Respuesta

44

"Tipos de reutilización en ensambles a los que se hace referencia" solo le permite volver a utilizar los Contratos de datos, no los Contratos de servicio. Si desea compartir contratos de servicio, no necesita utilizar "Agregar referencia de servicio" en absoluto. Puede simplemente usar ChannelFactory directamente.

// Supply the binding and address in code 
Binding binding = new BasicHttpBinding(); 
EndpointAddress address = new EndpointAddress("http://tempuri.org/address"); 
IServiceContract channel = ChannelFactory<IServiceContract>.CreateChannel(binding, address); 

// Or read them from the config file 
ChannelFactory<IServiceContract> channelFactory = new ChannelFactory<IServiceContract>(); 
IServiceContract channel = channelFactory.CreateChannel(); 

El objeto de canal también implementará ICommunicationObject, por lo que puede lanzar si es necesario llamar a métodos como Open() o Close().

+1

Gran solución, gracias –

+0

Iba con la segunda opción, pero me sale el error de que debe haber una EndpointAddress especificada. Tengo un punto final configurado en el archivo de configuración, con el mismo contrato (interfaz) especificado, pero no parece estar buscando allí? ¿Puede usted ayudar? –

+2

No importa; necesita pasar el nombre de la configuración del punto final al constructor ChannelFactory <>. –

4

Al crear la referencia de servicio, hay una caja que puede marque para que vuelva a utilizar las definiciones compartidas. Asegúrese de que el proyecto del cliente ya haga referencia al ensamblado compartido, agregue nuevamente la referencia del servicio y verifique todas las opciones cuidadosamente.

Si aún no funciona, verifique el enlace que usa. Tengo un recuerdo vago de que el enlace HTTP básico no admitirá la reutilización de tipos.

+0

Hola David, ¡gracias por el comentario! - He hecho exactamente eso, debería haberlo mencionado. :) 'Se verifican los tipos de reutilización en ensambles referenciados', y lo he intentado con 'Reutilizar tipos en todos los ensamblados referenciados' y 'Reutilizar tipos en ensamblados referenciados' mientras selecciono manualmente el ensamble en cuestión, ambos con el mismo resultado (como anteriormente). –

+0

El único problema con esa ruta es si desea hacer referencia a 2 servicios con la misma biblioteca compartida; obtienes objetos duplicados – eschneider

+0

@eschneider - No veo cómo es ese el caso, eso es lo que hace la opción 'Reutilizar ...', detiene la duplicación de clases ('objetos') mediante el uso de las clases referenciadas existentes, ¿no es así? Sin embargo, estoy viendo interfaces duplicadas, que es el problema que he descrito en mi pregunta :). –

2

Hay otra buena opción, si desea seguir utilizando el generador de proxy para su funcionalidad limitada, pero-poco-útil ... Utilice una clase parcial:

namespace <same namespace as generated proxy> 
{ 
    public partial class MyClient : <namespace of "real" service contract>.IServiceContract 
    { 
    } 
} 

Asegúrese de que el proxy es generar código de la misma manera que su Contrato de Servicio lo está definiendo, es decir, si está usando 'Lista', use esa opción en Configurar Referencias de Servicio también.En otras palabras, asegúrese de que la Interfaz de servicio generada sea exactamente igual a su Interfaz de servicio real y que el código anterior funcione, y actualice la referencia que utiliza con el botón derecho en lugar de escribir el código.

+0

Se siente como un truco pero funciona! –

2

Visual Studio no admite la reutilización de la interfaz existente al generar las clases proxy para usted. Los tipos de reutilización no reutilizarán la interfaz del contrato como señaló Quartermeister.

Lo hemos resuelto con herencia. Muy similar a la idea de clase parcial sugerida por Jester Software.

Ésta es la forma en que se resolvió:

En el proyecto de su cliente acaba de crear una referencia de servicio como lo habría hecho. A continuación, agregue una clase que sirve como el reemplazo para el cliente:

internal class MyServiceProxy : MyServiceClient, MyLogicNamespace.IMyService 
{} 

Esta clase hereda de la MyServiceClient generada, pero afirma que ese cliente hace implementar la interfaz original.

(sugiero se los pone en una carpeta denominada "ServiceProxies")

Si la clase MyServiceClient contiene ningún método que no coinciden con la interfaz original, entonces puede añadirlos en ese proxy y hacer la conversión en código.

Después de esto, simplemente utilice MyServiceProxy donde habría utilizado MyServiceClient.

Cuestiones relacionadas