2010-09-28 25 views
7

Je cherche un moyen de faire en sorte que la classe proxy générée pour une référence Web (pas WCF) implémente une interface commune afin de basculer facilement entre l'accès au service Web et l'accès "direct" à notre couche métier dans l'application cliente, quelque chose comme:Classe de proxy Web Service pour implémenter l'interface

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

Cependant, les types personnalisés (par exemple le CustomSerializableType dans les exemples ci-dessous) ne sont pas mentionnés dans la classe proxy générée. Au lieu de cela, de nouveaux types identiques sont générés, ce qui empêche la classe proxy d'implémenter l'interface.

Existe-t-il un moyen de faire référence à ces types de classes proxy générées, ou est-ce que je vais tout à fait mal? Dois-je envisager de convertir le service Web en un service WCF à la place?


Détails

Notre solution consiste à ces quatre projets:

  • Une bibliothèque d'affaires (contient la logique métier, les accès magasin de données)
  • Une bibliothèque commune (contient commune fonctionnalité, y compris le CustomSerializableType)
  • Un web ser vice (agit comme un proxy entre clients distants et la couche d'affaires)
  • fenêtres d'une application

Notre client souhaite l'application Windows pour pouvoir fonctionner dans deux modes différents:

  • mode local , où l'application utilise simplement la bibliothèque d'affaires directement aux données d'accès
  • mode distant, où l'application communique avec le service Web pour accéder aux données

Pour ce faire, nous avons créé une interface, IBusiness, qui se trouve dans la bibliothèque commune et contient toutes les méthodes de gestion.

Interface

public interface IBusiness 
{ 
    CustomSerializableType DoSomeWork(); 
} 

couche d'affaires

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

service Web

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

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

classe proxy généré (une tonne de code de gauche pour la lisibilité)

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

Utilisez-vous svcutil.exe pour générer les classes de proxy? –

+0

Non, pour le moment je n'utilise que des outils intégrés Visual Studio 2010. J'ai essayé de déconner un peu avec wsdl.exe, mais cela n'a pas résolu mes problèmes. Svcutil.exe est-il une alternative? Cela ne m'obligerait-il pas à passer aux services WCF, au lieu des services Web «hérités»? – bernhof

Répondre

6

En supposant que l'espace de noms par défaut de votre client est « Client », et que votre référence Web est nommé « Proxy », puis procédez comme suit ;

  1. À la racine de votre projet client, créez un dossier nommé "Proxy".
  2. Dans ce dossier, créez une classe appelée "Business".
  3. Faire cette interface classe publique et partielle, et l'ont mise en œuvre de votre IBusiness

De cette façon, vous n'avez pas besoin de modifier les Reference.cs. Vous devez jamais modifier Reference.cs, ou tout autre fichier produit par la génération de code.

Notez que cela viole les principes de la SOA en se liant étroitement votre client à votre service. À tout le moins, vous devez définir ces interfaces dans un projet distinct, de sorte que vous ne partagiez que le projet "interface" entre le client et le service.

+0

Mais qu'en est-il des types 'cloned' qui sont inclus dans Reference.cs (et dans certains cas, existent sous forme de fichiers .datasource sous Reference.map)? Ces classes modifient efficacement les signatures de méthode afin qu'elles ne correspondent pas à celles de l'interface, ce qui m'empêche de l'implémenter en premier lieu. Ou est-ce que je manque quelque chose ici? – bernhof

+0

Oui, vous avez manqué quelque chose! Si les types de proxy ne correspondent pas à l'interface, ils ne peuvent pas implémenter l'interface. Vous devrez créer votre propre ensemble de types distincts qui implémenteront l'interface, mais qui feront ensuite appel au service Web pour faire leur travail. C'est exactement ce que vous feriez si vous vouliez passer d'une implémentation utilisant une base de données à une autre utilisant un fichier XML. –

+0

Ainsi, afin d'appeler le service Web, je dois convertir manuellement les types référencés par l'interface (par exemple 'Common.CustomSerializableType') aux (clonés) types utilisés par la classe proxy (par exemple' Proxy.CustomSerializableType')? – bernhof