2009-09-17 5 views
6

Stiamo utilizzando WCF per la comunicazione tra un client e un'applicazione server. L'applicazione client ha molte funzionalità che richiedono la comunicazione al server -Servizio WCF che restituisce un altro servizio (fabbrica di servizi?)

Per il momento, stiamo creando nuovi endpoint WCF e contratti di servizio per ciascun oggetto - Fatturazione , Contabilità, Gestione dei contenuti, ecc. Questo causa un sacco di configurazione degli endpoint sia sul client che sul server (con potenziali problemi di errata configurazione durante lo spostamento nelle piattaforme di test e di produzione).

Vorrei sapere se è possibile definire un singolo endpoint WCF in grado di fornire più implementazioni di contatti di servizio. I nostri file di configurazione conterranno quindi un singolo endpoint (per la fabbrica di servizi) e posso richiedere servizi diversi specificando l'interfaccia del servizio a cui sono interessato.

ad es.

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); 
      } 

L'indizio di essere una singola configurazione endpoint per coppia di client/server, invece di una configurazione dell'endpoint per contattare il servizio mi piacerebbe mettere a disposizione.

È possibile?

risposta

1

Dubito che ciò funzioni. La serializzazione Xml potrebbe essere il problema più grande qui.

Inoltre, non credo che tu ne abbia realmente bisogno. Se fossi nei tuoi panni, proverei ad astrarre la mia comunicazione con il servizio. Fondamentalmente si invierà sempre un "Messaggio" al servizio, che ha un "Target" che è una delle classi a cui si desidera accedere. Il servizio rispondeva sempre con una "Risposta", di cui il contenuto sarebbe stato riempito dalla classe a cui il "Messaggio" era stato inviato.

Un altro approccio sarebbe quello di instradare tutti questi messaggi attraverso un servizio che farebbe eco alla richiesta al servizio appropriato. In questo modo si mantiene alta la scalabilità, ma il carico di configurazione è ancora elevato.

HTH.

+0

Grazie per la risposta.La serializzazione del servizio non è una soluzione, i metodi sul servizio devono essere gestiti sul server. I parametri devono essere serializzabili, ma il metodo stesso deve essere eseguito sul server. Ho trovato un documento su ServiceContracts con un SessionMode che sto provando ora. – Thies

+0

Non ho mai suggerito di serializzare un servizio. La serializzazione Xml è ciò che rende il WCF funzionante. È responsabile di prendere i tuoi oggetti e tradurli in Xml e viceversa. L'intero punto della mia risposta è quello di spiegare a voi che avvolgere le vostre richieste di servizio e le risposte potrebbe essere una soluzione al vostro problema. –

3

Non sono al 100% chiaro su cosa si sta tentando di fare, ma se si vuole solo essere in grado di ospitare diversi contratti sullo stesso indirizzo con l'implementazione all'interno di una classe di servizio, questo è completamente possibile. Per condividere un indirizzo endpoint, è necessario assicurarsi di utilizzare la stessa istanza di associazione per ciascun endpoint del servizio.

Ecco un esempio completo che definisce 3 contratti, 1 classe di servizio che implementa tutti loro, e un ServiceHost con i 3 punti finali contratto presso l'esatto stesso indirizzo:

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

Grazie, bobby, non è sempre facile definire un problema finché non si conosce la soluzione;). Come dichiari; Sono interessato ad ospitare molti contratti sullo stesso indirizzo, ma preferibilmente ho anche l'implementazione del servizio in diverse classi. Usando il tuo suggerimento avrei una singola classe 'mostro' che implementa tutti i servizi tramite il proxy delle chiamate sui servizi non WCF corretti, cosa che vorrei evitare. – Thies

+0

Sembra difficile ottenere tutto ciò che vuoi. Se si desidera che i client abbiano un buon contratto tipizzato, ma in realtà non si desidera che la classe di servizio li implementi, si rischia di scrivere un sacco di codice di elaborazione dei messaggi generici e di ignorare i comportamenti dei metadati WCF in modo che una corretta WSDL potrebbe ancora essere generato. – bobbymcr

0

Suona come si desidera mantenere i tuoi servizi separati ma hanno una sorta di bus che i percorsi sono in transito. Forse MSMQ, allora puoi avere un servizio che prende ogni messaggio e lo inserisce su una coda specifica e quindi un servizio dedicato può leggerlo da quella particolare coda.

Non proprio una soluzione basata su WCF, anche se certamente.

La nozione di un'interfaccia singola (leggi come ServiceContract) implementata da più classi non funziona. Quindi avresti bisogno di un servizio 'mostro' che attui tutti e instradi al servizio corretto. Mi viene in mente il modello di facciata.