c# - servicecontract - WCF Service Reference genera su propia interfaz de contrato, no reutilizará la mía
servicecontract c# (4)
"Tipos de reutilización en ensambles a los que se hace referencia" solo le permite reutilizar los Contratos de datos, no los Contratos de servicio. Si desea compartir contratos de servicio, no necesita utilizar "Agregar referencia de servicio" en absoluto. Puedes 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 convertirlo si necesita llamar a métodos como Abrir () o Cerrar ().
Mi primera pregunta, espero que sea adecuada:
Conjunto de interfaz compartido : tengo un ensamblado ''compartido'' que tiene una interfaz, llamémoslo IDocRepository
. Está marcado con [ServiceContract]
y hay varios métodos [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 de consumidores : 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 servicio generadas en el ensamblaje de consumidor derivan de una versión autogenerada de la interfaz:
public partial class ExampleClient : System.ServiceModel.ClientBase<SomeNamespace.ExampleSvcRef.IDocRepository>, SomeNamespace.ExampleSvcRef.IDocRepository {
Lo que esperaba
Hubiera esperado que ambas referencias heredasen 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é
Para que pueda crear una instancia de proxy de referencia de servicio y convertirlo a mi tipo de interfaz.
Entonces, ¿podría modificar el código generado a mano cada vez, pero debería haber una mejor manera ...?
(Editar: Tengo opciones de "Reutilizar tipos en los ensamblados a los que se hace referencia" y "Reutilizar tipos en todos los ensamblados a los que se hace referencia" para ambas referencias de servicio)
Cuando crea la referencia de servicio, hay un cuadro que puede marcar 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.
Hay otra buena opción, si desea continuar utilizando el generador de proxy para su funcionalidad limitada, pero algo ú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 esté generando 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.
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.
Así es como lo resolvimos:
En el proyecto de su cliente simplemente cree una referencia de servicio como lo hubiera hecho. A continuación, agregue una clase que sirva como reemplazo para el cliente:
internal class MyServiceProxy : MyServiceClient, MyLogicNamespace.IMyService
{}
Esta clase hereda del MyServiceClient generado pero establece que ese cliente implementa la interfaz original.
(Sugiero que los pongas en una carpeta llamada "ServiceProxies")
Si la clase MyServiceClient contiene algún método que no concuerde con la interfaz original, entonces puede agregarlos en ese proxy y hacer la conversión en el código.
Después de esto, simplemente use MyServiceProxy donde habría usado MyServiceClient.