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
e-mail: [EMAIL PROTECTED]
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
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 claseDiego, 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 entendidosaludosJoe----- Original Message -----From: [EMAIL PROTECTED]Sent: Wednesday, September 27, 2006 10:29 AMSubject: [puntonet] WebServices distindos compartiendo la misma claseHola, una pregunta referida a webservice con lo que me acabo de chocarTengo un proyecto con lo sigLibreria1- Clase1- ID- NombreSitio 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 clase1Los 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 areapero hay objetos en comun que pertenecen a la libreria de clases en comunProyecto Win1 (consumidor de webservice)//aca necesito del ws1 obtener la clase y luego pasarla a ws2pero aparecen problemas de conversion de tipos de datosAl invocar a WS1.Metodo1 tengo que crear una variableDim oo as WebService1.Clase1oo=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 objetoSi alguien llego hasta aqui y logro entender mi explicacion, es un exito, pero la pregunta es:1- si estoy haciendo las cosas muy mal2- es asi y no queda otra3- tengo que pasarlo como string de las clases serialziadas de alguna forma y olvidarme de pasar objetos4- ninguna de las opciones5- todas las opciones6- otra.......... (je)Desde ya muchas graciasIng. Diego M. Basélicae-mail: [EMAIL PROTECTED]UpSoft Sistemas InformáticosRafael Nuñez 3498 (X5009CFO) Córdoba, ArgentinaTel/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.
