2010-09-28 9 views
7

Sto cercando un modo per avere la classe proxy generata per un riferimento Web (non WCF) implementare un'interfaccia comune al fine di passare facilmente tra l'accesso al servizio Web e l'accesso "diretto" al nostro livello di business nell'applicazione client, qualcosa di simile:Classe proxy servizio Web per implementare l'interfaccia

public IBusiness GetBusinessObject() 
{ 
    if (_mode = "remote") 
    return new BusinessWebService.Business(); // access through web service proxy class 
    else 
    return new Business(); // direct access 
} 

Tuttavia, tipi personalizzati (ad esempio, il CustomSerializableType negli esempi qui sotto), non si fa riferimento nella classe proxy generato. Invece vengono generati nuovi tipi identici, il che rende impossibile per la classe proxy implementare l'interfaccia.

C'è qualche modo per fare riferimento alla classe proxy generata di questi tipi, o sto andando tutto sbagliato? Dovrei prendere in considerazione la possibilità di convertire il servizio web in un servizio WCF?


dettagli

La nostra soluzione si compone di questi quattro progetti:

  • Una libreria di business (contiene la logica di business, accessi archivio dati)
  • una libreria comune (contiene comuni funzionalità, incluso il CustomSerializableType)
  • Un web ser Vice (funge da proxy tra i client remoti e lo strato di business)
  • un'applicazione Windows

Il nostro cliente vuole l'applicazione di Windows per essere in grado di funzionare in due diverse modalità:

  • modalità locale , dove l'applicazione utilizza semplicemente la biblioteca di business direttamente per accedere ai dati
  • Modalità remota, dove l'applicazione comunica con il servizio web per accedere ai dati

Per fare ciò, abbiamo creato un'interfaccia, IBusiness, che si trova nella libreria comune e contiene tutti i metodi di business.

interfaccia

public interface IBusiness 
{ 
    CustomSerializableType DoSomeWork(); 
} 

strato di business

public class Business : IBusiness 
{ 
    public CustomSerializableType DoSomeWork() 
    { 
    // access data store 
    } 
} 

servizio Web

public class WebServiceBusiness : IBusiness 
{ 
    private Business _business = new Business(); 

    [WebMethod] 
    public CustomSerializableType DoSomeWork() 
    { 
    return _business.DoSomeWork(); 
    } 
} 

generato classe proxy (una tonnellata di codice lasciato fuori per migliorare la leggibilità)

public partial class Business 
    : System.Web.Services.Protocols.SoapHttpClientProtocol 
{ 

    public CustomSerializableType DoSomeWork() 
    { 
    // ... 
    } 

    public partial class CustomSerializableType { 
    // PROBLEM: this new type is referenced, instead of the 
    // type in the common library 
    } 
} 
+0

Si sta utilizzando svcutil.exe per generare le classi proxy? –

+0

No, al momento sto solo usando gli strumenti integrati di Visual Studio 2010. Ho provato a fare un pasticcio con wsdl.exe, ma non ha risolto i miei problemi. Svcutil.exe è un'alternativa migliore? Non mi richiederebbe l'aggiornamento ai servizi WCF, invece dei servizi Web "legacy"? – bernhof

risposta

6

Partendo dal presupposto che lo spazio dei nomi predefinito per il cliente è "Client", e che il riferimento web si chiama "proxy", quindi effettuare le seguenti operazioni ;

  1. Nella radice del progetto client, creare una cartella denominata "Proxy".
  2. In tale cartella, creare una classe denominata "Business".
  3. Fare quella classe pubblica e parziale, e lo hanno implementare il IBusiness interfaccia

In questo modo, non è necessario modificare le Reference.cs. È necessario mai modificare Reference.cs o qualsiasi altro file prodotto tramite la generazione del codice.

Nota che questo viola i principi di SOA vincolando strettamente il tuo cliente al tuo servizio. Per lo meno, è necessario definire tali interfacce in un progetto separato, in modo tale da condividere solo il progetto "interfaccia" tra il client e il servizio.

+0

Ma che dire dei tipi "clonati" inclusi in Reference.cs (e in alcuni casi esistono come file .datasource in Reference.map)? Queste classi cambiano in modo efficace le firme del metodo in modo che non corrispondano a quelle nell'interfaccia, impedendomi in tal modo di implementarla in primo luogo. O mi sto perdendo qualcosa qui? – bernhof

+0

Sì, ti sei perso qualcosa! Se i tipi di proxy non corrispondono all'interfaccia, non possono implementare l'interfaccia. Dovrai creare il tuo gruppo separato di tipi che implementano l'interfaccia, ma che poi invocano il servizio web per fare il loro lavoro. Questo è esattamente ciò che si farebbe se si volesse passare da un'implementazione che utilizzava un database e una che utilizzava un file XML. –

+0

Quindi per chiamare il servizio web, ho bisogno di convertire manualmente i tipi a cui fa riferimento l'interfaccia (ad esempio 'Common.CustomSerializableType') ai tipi (clonati) usati dalla classe proxy (ad esempio' Proxy.CustomSerializableType')? – bernhof