Publicado originalmente en FoxTalk.
Traducción de Jorge Espinosa.
Cuando
COM+ debutó en Windows 2000, introdujo varias nuevas capacidades para mejorar las aplicaciones en n-capas. Ahora con
VFP 7, puede usar estas mejoras para hacer sus aplicaciones más robustas. En esta primera parte, Craig Berntson hace una revisión acerca de
COMy
MTS para después introducirnos en
COM+.
Introducción a COM+
Por muchos años hemos escuchado acerca de la importancia de separar las aplicaciones en múltiples capas o servicios. Mediante la separación de la interfaz de usuario, las reglas de negocios y el acceso a datos, podemos fácilmente modificar o reemplazar completamente un servicio sin afectar a los demás.
Históricamente, las soluciones desarrolladas en
Visual FoxPro han sido soluciones de una sola capa, aún si la base de datos residiera en un servidor externo. Esto es así porque los desarrolladores mezclaban la interfaz de usuario, las reglas de negocio y el acceso a datos dentro de una aplicación o aun más, en el mismo formulario.
Con la aparición y uso de
SQL Server, hemos arribado a un escenario de dos capas. El dato es accedido normalmente vía
ODBC, ya sea, a través de Vistas Remotas o SQL Pass Trough. Los
Stored Procedures son a menudo ejecutados sobre el Server, y la sentencia SQL Select es resuelta del lado del servidor antes de enviar el resultado a través del cable. Esta separación del proceso dentro del servidor y las estaciones de trabajo, es lo que hace de esto un diseño en dos capas.
En una solución de tres capas, la interfaz de usuario solamente muestra datos y acepta ingresos de parte de los usuarios. Puede llegar a tener alguna validación menor, como el chequeo de que el usuario haya llenado los campos requeridos o la limitación de ingresos a través de un combo box. Mientras que todos los procesos de datos deben tener lugar en un componente separado que contenga todas las reglas de negocio. Cálculos de totales o tasas, validación de datos o la generación de reportes son ejemplos de lógica de negocios que deben estar encerrados en la capa intermedia. Finalmente, la tercer capa es responsable de la lectura y escritura dentro del repositorio de datos. La interfaz de usuario nunca debe tener acceso directo al repositorio de datos, debe llevar adelante esto a través de la capa de negocios para que esta haga el pedido al servidor de datos.
La separación de múltiples capas es lo que
Microsoft ha nombrado como
Distributed interNetworking Architecture o
DNA. Los diferentes componentes de cada servicio pueden residir en una misma máquina, haciendo una separación lógica de cada servicio o en múltiples máquinas llevando adelante así una separación física de cada capa. Típicamente, la interfaz de usuario reside en una computadora cliente, mientras que los componentes de negocios y acceso a datos residen en un servidor de aplicaciones, y el repositorio de datos en un segundo servidor. Cuando el acceso es vía Web, un servidor adicional para IIS (
Internet Information Server).
La vía para el acceso a estos componentes se realiza a través de
Component Objetc Model.
COM es la especificación que permite escribir componentes en diferentes lenguajes y que estos interactúen con cualquier otro. Por lo tanto, nosotros podemos crear componentes en
VFPque pueden ser accedidos desde aplicaciones desarrolladas en VB o Delphi, así como también desde Word o Excel. Los controles
ActiveX son un ejemplo de un objeto
COM. Cuando usted controla Word o Excel desde su aplicación
VFP, lo esta haciendo vía
COM.
Lo primero a considerar cuando se va a crear un componente
COM, es como este va a encajar con las demás partes de su aplicación. En otras palabras, usted necesita determinar si este será un objeto que correrá
in-process o
out-of-process.
Un componente
in-process es compilado como una
DLL y debe ser llamada por un programa ejecutable. Este corre en el mismo espacio de memoria de la aplicación -de allí su nombre
in-process- lo que hace que la instanciación del mismo sea más rápida. El dato es enviado a través de
COM. Como el componente corre en el mismo espacio de memoria que la aplicación, si este falla es muy probable que cause un fallo también en la aplicación. Otro dato a tener en cuenta, los servidores
in-process escritos en
VFP no pueden exponer ninguna interfaz de usuario.
Un servidor
out-of-process es compilado como un
EXE y corre en su propio espacio de memoria. Cuando este es instanciado, requiere de mas carga de trabajo, como la asignación de memoria, process id, etc. Esto lleva tiempo, lo que hace que el método del
out-of-process sea bastante mas lento que el de
in-process. Además es mas pesado el manejo de datos entre los componentes y la aplicación, por lo tanto es más lenta su ejecución. Por otro lado, al estar el componente corriendo en un espacio separado de memoria, si este fallara, la aplicación no sería alcanzada por este error y probablemente se mantuviera corriendo.
Creación de un componente COM
La creación de un componente
COM en
Visual FoxPro es muy fácil. La palabra clave
OLEPUBLIC en la creación de una clase, le dice a
VFPque compile el código con la información
COM necesaria para poder ser accedido desde otras aplicaciones.
Ejemplo:
DEFINE CLASS Math AS SESSION OLEPUBLIC
FUNCTION Multiply(tnNum1, tnNum2)
LOCAL lnResult
lnResult = tnNum1*tnNum2
RETURN lnResult
ENDFUNC
ENDDEFINE
Cuando usted crea el componente (Figura 1), puede elegir
"Win32 executable/COM Server(exe)" para crear un componente
out-of-process. Para crear un componente
in-process, seleccione
"Single-Threaded COM server (dll)" o "Muti-threaded COM server (dll)". Veremos mas acerca de la diferencia entre estos dos tipos de DLLs mas adelante. El componente quedará automáticamente registrado después de la compilación del mismo; de esta forma podrá instanciar el mismo mediante la función
CREATEOBJECT().
Figura 1.
Ejemplo:
ox=CREATEOBJECT("MyProject.Math")
? ox.Multiply(3,4) && Retornara 12
ox=NULL
Muchas de las reglas de
COM son automáticamente manejadas por
VFP. Sin embargo, debemos seguir una regla manualmente. Esta regla define que nunca debemos cambiar la interfaz de un componente. Si lo hacemos, necesitaremos crear un nuevo ID para el componente. Por interfaz, no debemos entender que nos referimos a interfaz de usuario, sino a los métodos públicos y parámetros del componente. Veamos esto sobre el ejemplo anterior. Si agregáramos un tercer parámetro al método Multiply, cambiaríamos la interfaz del componente y necesitaríamos generar un nuevo ID para el mismo. Esto lo podemos hacer desde el cuadro de diálogo
Build. La última opción en el cuadro de diálogo es
"Regenerate Component Ids". Marcando esta opción se genera una nueva interfaz para el componente.
Cuando comienza un desarrollo de componente
COM que se ejecute en un servidor remoto, usted debe tener en cuenta que el acceso a este servicio lo hará a través de
Distributed COM (DCOM). Históricamente, en
DCOM, usted distribuía un servidor del tipo
out-of-process y seteaba la información de acceso al mismo desde la computadora cliente. El capitulo 16 de la Guía del Programador de
Visual FoxProdetalla como llevar adelante este procedimiento. Cuando se instala el componente en un servidor remoto, el código se ejecuta del lado del servidor, no en el cliente. Es importante tener en cuenta no poner ningún tipo de interfaz gráfica de usuario en el código del componente, ya que esta se ejecutará en el servidor y no en la terminal del cliente.
MTS
Microsoft vio la necesidad de tener una mejor vía para ejecutar componentes remotos, entonces fue creado
Microsoft Transaction Server (MTS). Originalmente disponible para
Windows NT y
Windows 9x a través de NT 4.0 Option Pack,
MTS resolvió varios problemas ofreciendo un servidor para componentes
COM DLLs. Este proveía un asistente para realizar la configuración de los componentes
DCOMllamados desde el cliente por usted. Algunas otras características de
MTS son:
- Just-In.Time Activation: El componente permanece guardado en el disco y es cargado en memoria y activado solo cuando se necesita.
- Object Request Broker (ORB): MTS puede manejar múltiples llamadas al mismo componente desde múltiples clientes.
- Transaction Services: Commit y Aborts son manejados por el Distributed Transaction Coordinator (DTC) de la aplicación. Este hace posible tener transacciones que involucren a múltiples bases de datos.
- Role-based Security: El esquema de seguridad le permite determinar quien puede acceder sus componentes basado en los logins y grupos de NT. Si un usuario no tiene autorización para acceder un componente, un mensaje de error retornará al cliente indicando que el componente no pudo ser instanciado.
- Connection Pooling: Típicamente, una aplicación hace una conexión al repositorio de datos y la mantiene viva mientras la aplicación esté ejecutando. MTS permite a múltiples clientes utilizar una misma conexión.
La creación de componentes para el uso sobre
MTS requiere que usted cambie el pensamiento a la hora del diseño de sus aplicaciones. Primero, su aplicación debe mantenerse libre de estado (stateless). Esto significa que su programa cliente, debe instanciar el componente, hacer la llamada a los métodos y liberar el componente. La conexión al componente debe ser del menor tiempo posible. Usted debe evitar el seteo de propiedades y pasar toda la información necesaria como parámetros. Tenga en cuenta que
COM no permite a los parámetros ser pasados en el método
INIT.
Usted también necesita pensar en base a la ejecución por hilos
(threading). Típicamente pensamos acerca de la ejecución de un sistema como
single o
multi-threading.
VFP solo genera aplicaciones
single-threading. Esto significa que solo corre un proceso por vez. Esto es como ir al mercado y solo tener una caja abierta. Todos los clientes deben pasar a través de la misma caja. Solo un cliente a la vez puede ser atendido. Los demás deberán esperar en la cola para poder ser atendidos.
Multi-thread permite a sus aplicaciones separarse para ser procesadas por partes, corriendo todas al mismo tiempo. Tomando el ejemplo del mercado, usted podría descargar partes de su carrito de compras en diferentes cajas y que todos sus artículos comprados sean procesados al mismo tiempo.
MTS utiliza un tercer tipo de threading,
apartment model. Tomando nuevamente el ejemplo del mercado, los clientes pueden elegir entre cualquiera de las cajas abiertas, pero solo puede elegir una y siempre deberá usar la misma. Afortunadamente
MTS abrirá una nueva línea para usted si todas están en uso.
Entonces, ¿cómo hacemos uso de
MTS en nuestros componentes
VFP?. Primero, debemos agregar algo de código. Vamos a modificar el código de nuestro ejemplo Multiply para manejar
MTS.
DEFINE CLASS Math AS SESSION OLEPUBLIC
FUNCTION Multiply(tnNum1, tnNum2)
LOCAL lnResult, loMtx, loContext
*Creamos una referencia al Objeto MTS
loMtx=CREATEOBJECT("MTXAS.APPSERVER.1")
*Creamos la ref. al Contexto
loContext=loMtx.GetObjectContext()
lnResult=tnNum1*tnNum2
*Si hay alguna transacción abierta hacemos el Commit y avisamos al MTS
*que terminamos de usar el objeto.
loContext.SetComplete()
RETURN lnResult
ENDFUNC
ENDDEFINE
El objeto de contexto contiene información acerca de nuestra instancia en particular de nuestro componente
COM. También, observe la llamada a
SetComplete(). Esto hará un commit de cualquier transacción abierta que exista. Si necesitamos abortar la transacción, deberemos hacer una llamada a
SetAbort().
Cuando generamos nuestros componentes, no podremos usar la opción
"Win32 executable/COM server (exe)".
MTS requiere que los componentes sean .DLLs. Esto nos deja dos opciones:
single o
multi-threaded.
La DLL
single-thread es una buena opción cuando el método a llamar sea verdaderamente rápido o cuando un solo usuario tenga la posibilidad de llamarlo.
La DLL
multi-threaded en realidad no es multi-threaded, es un
Apartment Model Threaded. Tome esta opción cuando el método sea lento o cuando muchos usuarios vayan a hacer uso de este simultáneamente.
Una vez que haya creado el componente, instálelo en el servidor con las correspondientes bibliotecas. Entonces, debe proceder a crear el paquete
MTS e importar su componente usando el
MTS Explorer. Utilizando el
MTS Explorer, puede configurar la seguridad y soporte transaccional, también generar el programa de instalación cliente.
Windows 2000
Cuando Microsoft introdujo
Windows 2000, este vino con muchos servicios nuevos. Uno de estos es
COM+. Básicamente,
COM+ es la conjunción de
COM y
MTS, pero además
COM+ introdujo nuevas características. Sobre
Windows NT,
MTS corre sobre el sistema operativo. Sobre
Windows 2000, este se encuentra integrado al sistema operativo.
COM+ se encuentra disponible solamente en
Windows 2000. Mientras que, los usuarios de
Windows 95, 98, ME y NT pueden usar componentes
COM+ corriendo en un servidor
Windows 2000.
COM+, no solamente incluye (y mejora) las características de
MTS sino que agrega nuevos servicios como:
Queued Components (QC), Loosely Coupled Events (LCE), Object Pooling, y Dynamic Load Balancing. En adelante, iremos profundizando en detalle acerca de estos servicios.
Las aplicaciones
COM+ son administradas a través del
Component Services Manager (Figura 2). Puede encontrar esta en el grupo de programas Administrative Tools en el Windows Control Panel. Hagamos los pasos para ver que fácil es la registración de un componente.
Figura 2: Component Services Manager.
1.- Expandir el árbol debajo de
Component Services hasta tener disponible
COM+ Applications.
2.- Clic sobre
COM+ Applications para seleccionar el nodo, y clic con botón secundario sobre
COM+ Applications.
3.- En el menú contextual, seleccione
New Application para lanzar el asistente de
COM Applications. Presione el botón Next.
4.- Clic en la opción
"Create an empty Application" (Figura 3)
Figura 3.
5.- Ingrese el nombre de su aplicación. En el ejemplo lo hemos nombrado
MyFirstCOMApp. Seleccione el tipo de activación; normalmente usted seleccionará
Server Application debido a que su componente correrá sobre el servidor. Si desea instalar el componente en una terminal y correrlo en el espacio de memoria de su aplicación, entonces seleccione
Library Application (Figura 4). Seleccione Next.
Figura 4.
6.- Seleccione el ID de usuario con el cual el componente correrá. Cuando instale el componente sobre un servidor, es una buena práctica crear un usuario específicamente para instanciar sus componentes. Asegúrese de asignar a este los derechos necesarios, como por ejemplo que pueda tener acceso a todos los discos, directorios y recursos que pueda necesitar (Figura 5). Clic Next para finalizar.
Figura 5.
Ahora tenemos la aplicación instalada, pero todavía no contiene ningún componente. Debemos agregar el componente a la aplicación.
1.- Clic en el signo + en nuestra nueva
COM+ Application para expandir el árbol.
2.- Clic derecho sobre
Components. Seleccione
New Component desde el menú contextual para lanzar el asistente de
Component Install. Clic en Next.
3.- El asistente le ofrece tres opciones:
Install New Component, Import Component(s) that are already registered, o Install new event class(es). Nosotros tomaremos la tercera opción cuando hablemos acerca de
"Loosely Coupled Events". La segunda opción,
Import Component(s) that are already registered, es utilizada cuando se tiene el componente previamente instalado en la maquina. Esta opción no es recomendable ya que en su momento tuvo un bug de
Windows 2000 que no funcionaba correctamente. Lo que nos deja la opción 1. Clic en el botón Next para esta opción (ver Figura 6)
Figura 6.
4.- Seguidamente le solicitará seleccionar las DLLs a instalar. Si no tiene el runtime de
VFP instalado no podrá seleccionar e instalar su componente (Figura 7). Una vez que haya seleccionado su componente, clic Next para finalizar.
Figura 7.
¿Ahora que su componente está instalado, como lo accede?. De la misma manera que lo hacia antes. Utilizando
CREATEOBJECT() para instanciar el componente ¡y listo!
 | Craig Berntson es Microsoft Certified Solution Developer y fue nombrado cuatro veces Microsoft Most Valuable Profesional. Disertante de varias conferencias de FoxPro en todo EEUU y eventos de Microsoft en Salt Lake. Es Presidente del Salt Lake City Fox Users Group y actualmente ingeniero de software senior para 3m Health Information Systems. |
Jorge A. Espinosa, Buenos Aires (Capital Federal), Argentina, es Analista Programador y MCP. Dedicado al desarrollo de sistemas desktop desde el año 1987; siempre en el entorno xBase y en Visual Fox Pro desde la version 3.0. Hoy Gerente de Sistemas en Droguería Saporiti SACIFIA.