2009-09-17 22 views
6

Estamos utilizando WCF para la comunicación entre un cliente y una aplicación de servidor. La aplicación cliente tiene muchas características que requieren comunicación con el servidor, y hemos decidido implementar esto en múltiples clases (separación de responsabilidades)Servicio WCF que devuelve otro servicio (¿fábrica de servicio?)

Por el momento, estamos creando nuevos puntos finales WCF y contratos de servicio para cada objeto - Facturación , Contabilidad, Gestión de contenido, etc. Esto provoca una gran cantidad de configuración de punto final tanto en el cliente como en el servidor (con posibles problemas de configuración incorrecta al pasar a las plataformas de prueba y producción).

Me gustaría saber si puedo definir un solo punto final WCF que pueda ofrecer múltiples implementaciones de contacto de servicio. Nuestros archivos de configuración contendrían un solo punto final (para la fábrica de servicios) y puedo solicitar diferentes servicios especificando la interfaz del servicio en el que estoy interesado.

p.

using (IServiceClientFactory serviceClientFactory = new RealProxyServiceClientFactory()) 
      { 
       // This is normal WCF proxy object creation. 
       IServiceFactory serviceFactory = serviceClientFactory.CreateInstance<IServiceFactory>(""); 

       // This is what we would like to do 
       IInvoiceService invoiceService = serviceFactory.getService(typeof(IInvoiceService)); 

       invoiceService.executeOperation(data); 
      } 

La idea de ser una sola configuración de extremo por par cliente/servidor, en lugar de una configuración de punto final por contacto de servicio me gustaría poner a disposición.

¿Esto es posible?

Respuesta

1

Dudo que esto funcione. La serialización Xml podría ser el mayor problema aquí.

Además, no creo que realmente lo necesite. Si estuviera en su lugar, trataría de abstraer mi comunicación con el servicio. Básicamente, siempre enviaría un "Mensaje" al servicio, que tiene una "Meta" siendo una de las clases a las que quería acceder. El servicio siempre responderá con una "Respuesta", de la cual el contenido será llenado por la clase a la que se envió el "Mensaje".

Otro enfoque sería enrutar todos estos mensajes a través de un servicio que haría eco de la solicitud al servicio apropiado. De esta forma puede mantener la escalabilidad, pero aún así tiene una gran carga de configuración.

HTH.

+0

Gracias por la respuesta.Serializar el servicio no es una solución, los métodos en el servicio deben manejarse en el servidor. Los parámetros deben ser serializables, pero el método en sí debe ejecutarse en el servidor. Encontré un documento sobre ServiceContracts con un SessionMode que estoy probando ahora. – Thies

+0

Nunca sugerí serializar un servicio. La serialización Xml es lo que hace que WCF funcione. Es responsable de tomar sus objetos y traducirlos a Xml y viceversa. El objetivo de mi respuesta es explicarle que envolver sus solicitudes de servicio y respuestas puede ser una solución a su problema. –

3

No estoy 100% claro en lo que estás tratando de hacer, pero si solo quieres ser capaz de alojar diferentes contratos en la misma dirección con la implementación dentro de una clase de servicio, esto es completamente posible. Para compartir una dirección de punto final, debe asegurarse de usar la misma instancia de enlace para cada punto final de servicio.

Aquí es una muestra completa que define 3 contratos, 1 clase de servicio que implementa todos ellos, y una ServiceHost con los 3 puntos finales de contrato en la misma dirección:

using System; 
using System.ServiceModel; 

[ServiceContract] 
interface IContractA 
{ 
    [OperationContract] 
    void A(); 
} 

[ServiceContract] 
interface IContractB 
{ 
    [OperationContract] 
    void B(); 
} 

[ServiceContract] 
interface IContractC 
{ 
    [OperationContract] 
    void C(); 
} 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
class Service : IContractA, IContractB, IContractC 
{ 
    public Service() 
    { 
    } 

    public void A() 
    { 
     Console.WriteLine("A"); 
    } 

    public void B() 
    { 
     Console.WriteLine("B"); 
    } 

    public void C() 
    { 
     Console.WriteLine("C"); 
    } 
} 

class Program 
{ 
    public static void Main(string[] args) 
    { 
     Uri address = new Uri("net.pipe://localhost/Service/"); 
     ServiceHost host = new ServiceHost(new Service(), address); 
     NetNamedPipeBinding binding = new NetNamedPipeBinding(); 
     host.AddServiceEndpoint(typeof(IContractA), binding, string.Empty); 
     host.AddServiceEndpoint(typeof(IContractB), binding, string.Empty); 
     host.AddServiceEndpoint(typeof(IContractC), binding, string.Empty); 
     host.Open(); 

     IContractA proxyA = ChannelFactory<IContractA>.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(address)); 
     proxyA.A(); 
     ((IClientChannel)proxyA).Close(); 

     IContractB proxyB = ChannelFactory<IContractB>.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(address)); 
     proxyB.B(); 
     ((IClientChannel)proxyB).Close(); 

     IContractC proxyC = ChannelFactory<IContractC>.CreateChannel(new NetNamedPipeBinding(), new EndpointAddress(address)); 
     proxyC.C(); 
     ((IClientChannel)proxyC).Close(); 

     host.Close(); 
    } 
} 
+0

Gracias bobby, no siempre es fácil definir un problema hasta que conozca la solución;). Como dices; Estoy interesado en alojar muchos contratos en la misma dirección, pero preferiblemente también tengo la implementación del servicio en diferentes clases. Usando su sugerencia, tendría una sola clase de "monstruo" que implemente todos los servicios aprovechando las llamadas en los servicios correctos que no son de WCF, algo que me gustaría evitar. – Thies

+0

Parece difícil lograr todo lo que desea. Si desea que los clientes tengan un buen contrato escrito, pero en realidad no desea que su clase de servicio los implemente a todos, puede que esté atascado escribiendo un código de procesamiento de mensajes genérico extraño y anulando los comportamientos de metadatos WCF para que WSDL aún podría ser generado. – bobbymcr

0

suena como usted quiere mantener sus servicios separados, pero tienen algún tipo de autobús que las rutas son completas. MSMQ tal vez, entonces puede tener un servicio que lleve cada mensaje a una cola específica y luego un servicio dedicado puede leerlo de esa cola en particular.

Sin embargo, en realidad no es una solución basada en WCF.

La noción de una sola interfaz (leer como ServiceContract) implementada por múltiples clases no funcionará. Por lo tanto, necesitaría un servicio "monstruoso" que implemente todo y dirija el servicio correcto. El patrón de la fachada me viene a la mente.