2010-09-28 26 views
7

Estoy buscando una forma de tener la clase proxy generada para una referencia web (no WCF) implementar una interfaz común para cambiar fácilmente entre el acceso al servicio web y el acceso "directo" a nuestro capa de negocio en la aplicación cliente, algo así como:Clase proxy del servicio web para implementar la interfaz

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

sin embargo, los tipos personalizados (por ejemplo, el CustomSerializableType en los ejemplos siguientes) no se hace referencia en la clase de proxy generada. En su lugar, se generan tipos nuevos e idénticos, lo que hace imposible que la clase proxy implemente la interfaz.

¿Hay alguna manera de hacer que la clase de proxy generada haga referencia a estos tipos, o me estoy equivocando? ¿Debo considerar convertir el servicio web a un servicio WCF?


detalles

Nuestra solución consiste en estos cuatro proyectos:

  • Una biblioteca de negocios (contiene la lógica de negocio, los accesos de almacén de datos)
  • una biblioteca común (contiene común funcionalidad, incluido el CustomSerializableType)
  • Un servidor web vice (actúa como un proxy entre clientes remotos y la capa de negocio)
  • una aplicación de Windows

Nuestro cliente quiere que el uso de las ventanas para poder funcionar en dos modos diferentes:

  • modo local , donde la aplicación simplemente usa la biblioteca comercial directamente para acceder a los datos
  • Modo remoto, donde la aplicación se comunica con el servicio web para acceder a los datos

Para ello, hemos creado una interfaz, IBusiness, que se encuentra en la biblioteca común y contiene todos los métodos comerciales.

interfaz

public interface IBusiness 
{ 
    CustomSerializableType DoSomeWork(); 
} 

capa de negocios

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

servicio web

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

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

generada clase proxy (una tonelada de código dejado fuera para facilitar la lectura)

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

¿Está utilizando svcutil.exe para generar las clases de proxy? –

+0

No, en este momento solo estoy usando las herramientas integradas de Visual Studio 2010. Intenté jugar un poco con wsdl.exe, pero no resolvió mis problemas. ¿Es svcutil.exe una mejor alternativa? ¿No me requeriría eso actualizar a los servicios de WCF, en lugar de los servicios web 'heredados'? – bernhof

Respuesta

6

Suponiendo que el espacio de nombres predeterminado para su cliente es "Cliente", y que su web de referencia se denomina "proxy", a continuación, haga lo siguiente ;

  1. En la raíz de su proyecto de cliente, cree una carpeta llamada "Proxy".
  2. En esa carpeta, crea una clase llamada "Negocio".
  3. Hacer que la clase pública y parcial, y tienen que poner en práctica su IBusiness interfaz

De esta manera, no es necesario modificar los Reference.cs. Debe nunca modificar Reference.cs, o cualquier otro archivo producido a través de la generación de código.

Tenga en cuenta que esto infringe los principios de SOA al vincular estrechamente a su cliente a su servicio. Como mínimo, debe definir esas interfaces en un proyecto separado, de modo que solo comparta el proyecto de "interfaz" entre el cliente y el servicio.

+0

¿Pero qué pasa con los tipos 'clonados' que se incluyen en Reference.cs (y en algunos casos existen como archivos .datasource en Reference.map)? Estas clases cambian de manera efectiva las firmas de método para que no coincidan con las de la interfaz, impidiéndome implementarlo en primer lugar. ¿O me estoy perdiendo algo aquí? – bernhof

+0

Sí, te perdiste algo! Si los tipos de proxy no coinciden con la interfaz, entonces no pueden implementar la interfaz. Tendrá que crear su propio conjunto de tipos que _do_ implementen la interfaz, pero que luego soliciten al servicio web que haga su trabajo. Esto es exactamente lo que haría si quisiera cambiar entre una implementación que usó una base de datos y otra que usó un archivo XML. –

+0

Entonces, para llamar al servicio web, necesito convertir manualmente los tipos a los que hace referencia la interfaz (por ejemplo, 'Common.CustomSerializableType') a los tipos (clonados) utilizados por la clase proxy (por ejemplo,' Proxy.CustomSerializableType'). – bernhof

Cuestiones relacionadas