Continuando con el artículo de introducción a CAB, en este post voy a explicar los conceptos básicos de Smart Client Software Factory (SCSF), el proyecto que nos permite automatizar el desarrollo de aplicaciones compuestas usando CAB.
Si ya estuvieron haciendo pruebas con CAB se habrán dado cuenta de que se requiere mucho trabajo extra para crear los nuevos elementos como ser, Workitems, Presenters, Controllers, publicaciones y subscripciones a eventos y comandos, etc.. SCSF nos ofrece un conjunto de asistentes (recipes) y guías que nos ayudan a crear estos elementos en forma automatizada y empleando un diseño adecuado.
Básicamente, SCSF es un agregado para el Visual Studio que añade nuevos tipos de proyectos y asistentes para la creación automatizada de los elementos nombrados. SCSF también posee proyectos de ejemplos (Hands on Labs y Quickstarts) y documentación que nos guían en el aprendizaje e implementación de aplicaciones SCSF.
Si en este artículo encuentra alguna palabra que desconoce es probable que encuentre su definición en el Glosario de CAB en mi post anterior de Introducción a Composite UI Application Block.
¿Qué nos ofrece SCSF?
Con SCSF se obtienen todos los beneficios del desarrollo de aplicaciones con CAB, y además:
- Automatización de varias tareas del desarrollo de una aplicación CAB/SCSF.
- Guías para las tareas que no pueden ser automatizadas.
- Nuevos elementos que añaden y extienden las funcionalidades originales de CAB (ej. Entity Translator, Disconnected Service Agent, Action Catalog).
- Ejemplos, documentación y muchos recursos para el aprendizaje.
- Excelente soporte en el foro del proyecto en CodePlex.
Nuevos elementos
Los proyectos que sean creados usando SCSF poseen en la misma solución un conjunto de clases que añaden nuevas funciones o que encapsulan los elementos originales de CAB. Los nuevos elementos y conceptos que se deben de tener en cuenta en SCSF son:
Nota: Es importante tener en cuenta que la siguiente lista es sólo de algunos de los conceptos más importantes introducidos por SCSF y por lo tanto deja de lado muchos conceptos de CAB que son de vital importancia y que requieren ser abordados previamente para un correcto entendimiento.
- Recipe: un asistente en el Visual Studio que nos automatiza la creación de algún elemento de CAB/SCSF.
- WorkItemController: con SCSF en lugar de heredar nuestros WorkItems de la clase WorkItem podemos heredar de la clase abstracta WorkItemController, esta clase contiene un workitem asociado al cual podemos acceder por medio de la propiedad WorkItem. De esta forma, logramos una mejor separación de responsabilidades del WorkItem, que anteriormente actuaba como contenedor
(Items, Services, WorkItems) y como lugar donde se colocaba la lógica de negocio de los casos de uso. Ahora el WorkItem sólo actúa como conteneder y nuestra clase que hereda de WorkItemController es el lugar donde colocamos la lógica de negocio.
- ControlledWorkItem: es una clase genérica (debemos indicarle un WorkItemController) que nos ayuda a instanciar nuestro WorkItem que hereda de WorkItemController.
- Business Module: es un proyecto (DLL) que contiene una unidad del negocio junto con sus vistas (ej. Módulos Clientes, Stock, Administración, etc.). Cada Business Module tienen un WorkItemController principal llamado ModuleController.
- ModuleController: es una clase que hereda de WorkItemController que toma el papel de WorkItem raíz para el módulo de negocio. En esta clase es donde realizaremos gran parte de las
tareas de inicialización del módulo (agregar vistas, añadir ítems a los extension sites, registrar servicios, etc.).
- Fundational Module: al igual que un Business Module, es una DLL pero generalmente no poseen vistas y no tienen WorkItems. Se emplean, principalmente, para contener servicios globales que utilizan otros módulos (ej. Módulo Logging, Seguridad, Acceso a Datos, etc.). Todos los módulos (tanto fundational como business) tienen una clase Module que hereda ModuleInit con un método Load para que puedan ser cargados por CAB.
- Action Catalog: servicio de SCSF que implementa un patrón que permite ejecutar acciones basado en condiciones que cambian en tiempo de ejecución.
- Disconected Service Agent: SCSF provee un recipe para crear disconnected service agents (DSA). DSA es un servicio que permite abstraer un servicio web para poder usarlo en forma desconectada cuando el servicio no está disponible.
- Entity Translator: servicio de SCSF que permite transformar una entidad de negocio a otro tipo de entidad requerida por servicios externos.
Solución inicial
Cuando creamos un proyecto de SCSF, este nos crea una solución con varios proyectos listos para funcionar que se encuentran organizados en un conjunto de carpetas. Los proyectos iniciales que se
encuentran en la carpeta Infrastructure son proyectos básicos para el funcionamiento de la aplicación y que brindan los servicios sobre los que se construyen los demás módulos que componen la
aplicación. Dependiendo de la configuración que hayamos elegido en la recipe al momento de crear el proyecto, nuestra solución contendrá básicamente los siguientes proyectos:
- Infrastructure.Interface: contiene elementos globales que necesitan ser expuestos a los módulos de la aplicación como ser: interfaces de los servicios de infraestructura, definiciones de constantes, entidades de negocio que necesitan ser pasadas entre varios módulos, etc.
- Infrastructure.Library: contiene las implementaciones de los elementos comunes para todas las aplicaciones SCSF como ser los servicios de trasformación de entidades, del DSA, carga
del ProfileCatalog desde un Web service, etc.
- Infrastructure.Module: es un business module vacío que podemos usar para la implementación de cualquier elemento que necesita ser compartido por varios módulos de la aplicación.
- Shell: al igual que una aplicación CAB, es el proyecto inicial que tiene el ProfileCatalog.xml para cargar los módulos y crea el WorkItem raíz y contiene el formulario Shell que posee la interfaz básica con los Workspaces para desplegar las vistas.
- Infrastructure.Layout: es un módulo que contiene una vista en la que se diseña la interfaz común
dejando a la shell prácticamente vacía, logrando una mejor separación de responsabilidades y facilitando el reemplazo y reutilización de la interfaz común de la aplicación. Este proyecto se crea sólo si se tildó la opción para crear un módulo separado para el layout del shell.
Los siguientes pasos, una vez que ya tenemos la solución para comenzar a trabajar, son:
- Modificar la Shell si la interfaz por default no es lo que necesitamos.
- Crear los módulos fundacionales que expondrán servicios para el resto de la aplicación.
- Crear los módulos de negocio, las vistas y demás elementos necesarios.
Si empleamos TDD, luego de crear cada módulo y antes de seguir con la implementación del módulo, debemos crear las pruebas y seguir con el proceso del desarrollo dirigido por pruebas.
Todas estas tareas pueden hacerse en forma automatizada usando las recipes que nos ofrece SCSF.
¿Cómo se hace en SCSF?
Una situación común en la gente que empieza con SCSF es preguntarse cuál es la forma en que se hace determinada cosa en SCSF, o dónde tengo que poner tal cosa o cuál es la forma correcta de hacer tal otra cosa. Ésta desorientación en los principiantes se puede deber a la gran cantidad de guías y lineamientos que ofrece SCSF para hacer las cosas, dando la sensación que en SCSF existe una forma específica de hacer cada tarea para que funcione.
En realidad, SCSF y CAB son una extensión de funcionalidades que nos ayuda a crear mejores aplicaciones siguiendo una limitada selección de prácticas recomendadas, pero no pretende ser la solución perfecta para todas las situaciones posibles.
En una aplicación SCSF se pueden implementar una cosa de mil formas distintas o como lo hacemos siempre en cualquier aplicación y va a funcionar sin demasiados problemas. SCSF sólo nos facilita realizar una limitada cantidad de tareas en una forma organizada.
Sin embargo, cuando somos ajenos a los patrones y prácticas que se utilizan en CAB/SCSF podemos seguir sin saberlo caminos que nos pueden llevar a encontrarnos con dificultados. A continuación sugiero algunos tips que considero pueden ayudar en esta toma de decisiones:
- Utilizar un módulo separado para el layout cuando tengamos mucha lógica de presentación para la interfaz común que no queremos mezclar con las demás responsabilidades del proyecto Shell (el
proyecto Interface.Layout tiene un ModuleController y el Shell no), o cuando queremos reutilizar la interfaz común o poder “switchearla” dinámicamente (ej. según preferencias del usuario).
- Las vistas deberían contener el mínimo posible de lógica. La gran parte son llamadas a funciones en el presenter para informar de eventos y propiedades y eventos que el presenter usa para. El presenter contiene la lógica para manejar los eventos y actualizar la vista y el modelo.
- Es recomendable siempre usar interfaces (principalmente en vistas y servicios) para poder intercambiar las implementaciones y facilitar el testing.
- Usar siempre constantes para los identificadores de comandos, eventos, extensión sites, etc..
- No usar la misma cadena para identificar un Evento y un Comando. CAB no distingue entre eventos y comandos del mismo nombre y puede traer problemas.
- Crear un WorkItem para contener los datos o información de contexto que necesita ser comunicado a los presenters de las vistas de un módulo. Un error común es pasar información a una
vista o presenter por medio de los parámetros de un evento (Event Broker), es mejor usar States.
- Utilizar Event Broker cuando se necesita informar de eventos a toda la aplicación sin importar quién lo reciba.
- TDD es una muy buena práctica que SCSF tiene en cuenta.
- Gran parte de la lógica de negocio, incluyendo inicializaciones, comandos, y eventos suelen quedar en los ModuleController, es muy normal.
Pueden existir más recomendaciones, pero lo importante es conocer todos los elementos y herramientas que podamos tener a nuestro alcance y comprender bien cuál es el cometido de cada uno, de esta forma sabremos qué usar en cada escenario y cómo, logrando la combinación más conveniente.
Lecturas recomendadas:
En este post se pasaron por alto los detalles técnicos del uso de SCSF y que escapan al alcance de este post, para eso recomiendo seguir los Hands on Lab que son muy didácticos para el aprendizaje de este excelente framework.
Leave a reply