1) Inicial: Atacar directamente a la DLL
 
Si por ejemplo en la capa de negocio tenemos el método:
Function ObtenerPersona(pFiltro as PersonaRequestClass) as PersonaClass
 
Luego desde el cliente es fácil atacar directamente a la DLL y hacer:
Dim filtro as new CapaNegocio.PersonaRequestClass
... rellenar filtros...
Dim persona as CapaNegocio.PersonaClass = CapaNegocio.ObtenerPersona(filtro)
y esto funciona perfectamente, aquí no hay ningún problema.
 
 
2) Complicación: Atacar directamente al webService
 
El problema es si metemos un webService en medio, entonces hay que tocar todo el código del cliente
Dim filtro as new webService.PersonaRequestClass
... rellenar filtros...
Dim persona as webService.PersonaClass = webService.ObtenerPersona(filtro)
 
Nota: lo siguiente no funciona porque daría un error de cast porque son clases distintas:
Dim persona as CapaNegocio.PersonaClass = webService.ObtenerPersona(filtro)
 
 
3) Solución: Atacar siempre a un intermediario
 
Para evitar este problema, puedes crear OTRO proyecto en el cliente y atacar siempre a este proyecto (desde el cliente).
Dim filtro as new intermediario.PersonaRequestClass
... rellenar filtros...
Dim persona as intermediario.PersonaClass = intermediario.ObtenerPersona(filtro)
 
Veamos ahora el código dentro del proyecto intermediario (que está en la capa del cliente)
Function ObtenerPersona(pFiltro as PersonaRequestClass) as PersonaClass
IF appSettings("ViaDeAcceso")="DLL"
  RETURN CapaNegocio.ObtenerPersona(pFiltro)  'ataco directamente a la capa de negocio
ELSE
  dim wsFiltro as webService.PersonaRequestClass = _ConvertirFiltro_DLL_to_WS(pFiltro)
  Dim wsPersona as webService.PersonaClass = webService.ObtenerPersona(wsFiltro)
  RETURN _ConvertirPersona_WS_to_DLL(wsPersona)
END IF
Nota: faltaría hacerle un New al webService y algún que otro detalle (estoy escribiendo de memoria solo para ejemplificar)
 
Como ves, el cliente nunca se entera si está atacando a la DLL o a un webService (basta cambiar "ViaDeAcceso" en el web.config)
El intermediario siempre devuelve una clase del tipo de la DLL (sea que voy por DLL o por webService)
El gran inconveniente, es que tenés que desarrollar las funciones que puse en rojo.
O sea: hay que convertir parámetros a mano, tanto a la ida como a la vuelta...
 
 
4) Solución para convertir los parámetros a la ida y a la vuelta.
 
La clase PersonaClass, tanto en el webService como en la DLL, tienen la misma representación XML
De hecho, el webService no hace más que "serializar" (convertir automáticamente las clases en un string XML) o "deserializar" (la inversa)
Si comparamos los XML resultantes (tanto de la clase de la DLL, como de la clase del webService) veremos que tienen los mismos tags.
Sugiero por tanto "engañar" a la máquina, serializando la clase del webService y deserializando en la clase de la DLL
Pongo ahora el ejemplo concreto:
Dim persona as CapaNegocio.PersonaClass = _Deserializar( _Serializar(webService.PersonaClass) )
_Serializar convierte la clase del webService en su representación XML
_Deserializar convierte el XML en la clase de la DLL
 
Entonces el proyecto intermediario (me refiero al punto 3) quedaría como sigue:
 
Function ObtenerPersona(pFiltro as PersonaRequestClass) as PersonaClass
IF appSettings("ViaDeAcceso")="DLL"
  RETURN CapaNegocio.ObtenerPersona(pFiltro)
ELSE
  dim wsFiltro as webService.PersonaRequestClass = _Deserializar(_Serializar(pFiltro))
  Dim wsPersona as webService.PersonaClass = webService.ObtenerPersona(filtro)
  RETURN _Deserializar(_Serializar(wsPersona))
END IF
 
La segunda parte (la del ELSE) se podría poner en una sola línea y entonces queda resumido:
Function ObtenerPersona(pFiltro as PersonaRequestClass) as PersonaClass
IF appSettings("ViaDeAcceso")="DLL"
  RETURN CapaNegocio.ObtenerPersona(pFiltro)
ELSE
 RETURN _Deserializar(_Serializar(webService.ObtenerPersona(_Deserializar(_Serializar(pFiltro)))))
END IF
 
Hasta aquí entonces tenemos la discusión filosófica, repito que el código no lo he probado y es solo ejemplificativo.
La funcion _Serializar es genérica, admite cualquier objeto como parámetro de entrada.
La funcion _Deserializar también es genérica, aunque hay que indicarle el tipo que esperas recibir.
Te paso si querés ambas funciones, con mayores ampliaciones llegado el caso.
 
Resumen Final:
 
Yo creo que el último punto 4 resuelve tus mayores dudas: cómo forzar a que devuelva siempre la misma clase y no la clase proxy ?
La respuesta es: hay que hacerlo a pedal (aunque las funciones genericas _Serializar() y _Deserializar() ayudan mucho).
 
Pero me he permitido sugerir el proyecto intermedio, para que la disyuntiva DLL/webService quede oculta al cliente.
Evidentemente, cada vez que tocás un método en la DLL, tendrías que tocarlo también en el proyecto intermediario...
 
Mientras estamos en desarrollo, ponemos ViaDeAcceso="DLL" y solo al final "apuntamos" al webService.
Esto me permite implementar el webService al final y recién ahí me curro todos los ELSE del intermediario.
O sea que en desarrollo no hay más que copiar y pegar los métodos de la DLL (como si fuera un interface).
 
Pata.
 


De: [email protected] [mailto:[EMAIL PROTECTED] En nombre de [EMAIL PROTECTED]
Enviado el: miércoles, 18 de octubre de 2006 18:54
Para: puntonet List Member
Asunto: [puntonet] WebServices distindos compartiendo la misma clase

Joe:
    Hice lo que vos me decis, y funciona. Pero lamentablemente es bastante complejo y tedioso, ya que como estamso en pleno desarrollo, creando constantemente WS, se hace muy dificir hacer los cambios a mano
 
    Pregunta para todos,
    Existe algun atributo que se pueda colocar al metodo, similar a WebMetod() donde se le pueda indicar que en vez de crear una clase nueva proxy, utilice una clase determinada y al genear la clase reference la use sin crear el proxy?
 
    Por ejemplo, algo muy simple, Tengo un WebMetod que devielve un DataTable, y cuando genera el proxy crea una clase que enmascara al Datatable, pero luego desde el cliente no se ve como datatable
    Lo que yo queria lograr es obligarlo a que devuelva un DataTable
 
    Este es solo un ejemplo, ya que si lo hago con DataSet funciona y listo, pero es para que tengan una idea.
    Gracias
 
Ing. Diego M. Basélica
 
UpSoft Sistemas Informáticos
Rafael Nuñez 3498 (X5009CFO) Córdoba, Argentina
Tel/Fax: 0351-4814812 (rot.)


De: [email protected] [mailto:[EMAIL PROTECTED] En nombre de Joe Joe
Enviado el: Martes, 03 de Octubre de 2006 21:27
Para: puntonet List Member
Asunto: [puntonet] WebServices distindos compartiendo la misma clase

bueno, esa es la parte que todabia no resolvi..cada vez que modifico el WS, el reference.cs del proxy en el cliente se actualiza y tengo que volver a escribir el using "Entidades" y borrar las declaraciones de las clases (la verdad es que tardo 30 segundos en hacerlo ,asi que nunca me preocupe en ver como evitarlo.... ;)...pero sacando ese laburito que seguro algun guru nos dira como evitarlo creo que es la solucion a adoptar para poder usar la misma clase en los distintos elementos del sistema....
 
saludos,
 
Joe





 

From: [EMAIL PROTECTED]
To: [email protected]
Subject: [puntonet] WebServices distindos compartiendo la misma clase
Date: Tue, 3 Oct 2006 19:04:44 -0300

gracias por el dato,
el tema que tengo miedo, es que como estamos recien armando los WS, si cambi el reference, la proxima vez que agregue uno nuevo metodo y se actualice, me va apisar lo que modifique


De: [email protected] [mailto:[EMAIL PROTECTED] En nombre de Joe
Enviado el: Viernes, 29 de Septiembre de 2006 18:22
Para: puntonet List Member
Asunto: [puntonet] WebServices distindos compartiendo la misma clase

 Diego, si no entedi mal, lo que deberias hacer es poner la liberiaria1 en un proyecto independiente (por ejemplo uno que se llame Entidades), luego la referencias en todos los poryectos y particularmente en el cliente vas a tener que modificar el reference.cs de ambos proxys borrando el codigo donde genera la clase1 y agregando el using correspondiente a Entidades....
 
 De esta manera todos estan usando la misma clase1  (Entidades.Clase1)
 
espero que se haya entendido
 
saludos
 
Joe
 
 
----- Original Message -----
Sent: Wednesday, September 27, 2006 10:29 AM
Subject: [puntonet] WebServices distindos compartiendo la misma clase

Hola, una pregunta referida a webservice con lo que me acabo de chocar
Tengo un proyecto con lo sig
 
Libreria1
    - Clase1
        - ID
        - Nombre
 
Sitio Web1
    - WebService1   
        - Metodo1(pID) as Clase1     //un metodo que devuelve una instancia de la clase1
 
 
    - WebService1   
        - Metodo1(pObj as Clase1)     //un metodo que devuelve una instancia de la clase1
 
 
Los web service los tengo separados por organizaion, ya que no tienen solo un metodo, el primero es el encargado de la seguridad y los otros so nrelativos a cada area
pero hay objetos en comun que pertenecen a la libreria de clases en comun
 
 
 
Proyecto Win1  (consumidor de webservice)
//aca necesito del ws1 obtener la clase y luego pasarla a ws2
pero aparecen problemas de conversion de tipos de datos
 
Al invocar a  WS1.Metodo1 tengo que crear una variable
 
    Dim oo as WebService1.Clase1
    oo=WebService1(2)
 
    WebService2.Metodo1(oo)  --->> falla porque si bien la clase es la misma, para cada ws crea un proxy distinto y me indican que no son el mimo objeto
 
 
Si alguien llego hasta aqui y logro entender mi explicacion, es un exito, pero la pregunta es:
    1- si estoy haciendo las cosas muy mal 
    2- es asi y no queda otra
    3- tengo que pasarlo como string de las clases serialziadas de alguna forma y olvidarme de pasar objetos
    4- ninguna de las opciones
    5- todas las opciones
    6- otra.......... (je)
 
 
Desde ya muchas gracias
 
 
 
 
 
Ing. Diego M. Basélica
 
UpSoft Sistemas Informáticos
Rafael Nuñez 3498 (X5009CFO) Córdoba, Argentina
Tel/Fax: 0351-4814812 (rot.)
 


Envía mensajes de correo electrónico directamente a tu blog con MSN. Carga chistes, fotografías y muchas otras cosas. Es gratis.

Responder a