¡Buenos días!
Como muchos ya sabéis, Microsoft dentro de su MSDN tiene un departamento de arquitectura, Microsoft Patterns and Practices (p&p), que ofrecen a los desarrolladores (nosotros) buenas prácticas para obtener una solución de la forma más eficiente para nuestro día a día y además aplicando de una forma práctica patrones para una solución común de nuestros problemas del día a día. En p&p existen proyectos como Enterprise Library, Web Client Software Factory... y la que voy a tratar ahora, Smart Client Software Factory (SCSF).
SCSF, nos propone una alternativa a la forma de trabajo de winforms. De forma diaria, cuando se desarrolla un aplicación para él desktop creamos nuestra solución con un proyecto para la interface de usuario (UI), para nuestra lógica de negocio (BL) y para el acceso a datos (DAL). En nuestro proyecto de UI tendremos el winforms con "n" elementos en el formulario (MeForm.cs) y cada uno tendrá su code behind dónde implementaremos, por ejemplo, el evento button_Click de nuestro botón del formulario que llamará a BL y esta a DAL.
Con SCSF, además de aplicar buenas prácticas de una forma fácil en nuestros clientes complejos desktop basado en Composite UI Application Block (CAB), obtenemos una arquitectura de nuestra aplicación más usable, más universal y con más facilidad de mantener; podemos decir que nos ayuda en el ciclo de vida de nuestra aplicación. SCSF, usa y se basa principalmente en Composite UI Application Block y para ello debemos introducir una série de definiciones algo complejas.
- WorkItem: es un contenedor para el manejo de de objetos, que son necesarios para el cumplimiento de una tarea determinada. Tales objetos son objetos de estado, vista y sus presentadores, o comandos para lanzar una acción. En resumen, es una clase que resume la lógica de un caso de uso que conoce todos los diferentes aspectos.
- Service: Un servicio encapsula la funcionalidad que es común para toda la aplicación cliente, por un módulo específico, o simplemente WorkItems.
- Module: Múltiples WorkItems pueden resumirse en una sola unidad de despliegue. CAB trabaja básicamente a nivel de módulos por lo tanto encontrar la forma de encapsular los WorkItems en los módulos es fundamental.
- ProfileCatalog: es sólo la configuración que especifica que los módulos y los servicios tienen que ser cargados en la solicitud. Es un archivo XML que reside en el directorio de aplicación.
- ModuleLoader: Se trata un servicio general CAB, que es responsable de cargar todos los módulos descritos en un catálogo de peril.
- ModuleInt: Cada módulo tiene una clase ModuleInt que se encarga de cargar todos los servicios y WorkItems de un módulo. Además también es responsable de la interfaz de usuario.
- Command: es una clase de CAB que aplica el patrón Command, de forma resumida, CAB encapsula este patrón [CommandHandler] como atributo de módulo que permite llamar a una operación de un objeto sin saber cúal el contenido de la operación ni el receptor de la misma.
- Shell Application: La aplicación de Shell es la principal que se encarga de inicializar la aplicación. Es la responsable de la carga dinámica de módulos y de la puesta en marcha de los servicios para la aplicación cliente inteligente, además de iniciar el formulario principal, el Shell.
- Shell: Proporciona la interfaz de usuario que es común a todos los módulos de carga dinámica. La Shell sioempre contiene el WorkItem principal, servicios, módulos y el registro de los mismos.
- Workspace: es un control que es el principal responsable para mostrar elmentos de la interfaz de usuario creados por los WorkItems. El WorkItem se añade al Shell y actúa como contenedor de la interfaz de usuario proporcionada por WorkItems. Si queremos que un control de usuario sea un workspace, solo debemos implementar la interfaz IWorkspace.
- UIExtensionSite: son marcadores de posición especiales para la amplicación de partes fijas del Shell, tales como los menús, barras de herramientas... Se diferencián de los workspace por que estos están destinados a ser utilizados por todas las partes de la interfaz de usuario que no deben ser anuladas por los WorkItems, si no que deben ser ampliadas. Por ejemplo, podemos hacer un override del método principal de creación de menús y a parte de los base podemos añadir otra opción necesaria para ese WorkItem.
- EventBrokers: Hay dos, EventPublication y EventSubscription. El primero de ellos se lleva a cabo a través de .NET Framework marcando los eventos con el atributo [EventPublication] y el segundo, para cualquier clase que quiera suscribirse a un evento tiene que aplicar un manejador de evento que conicida con el la firma del método del evento publicado y debe marcar este evento con [EventSubscription].
- View: Es un control de usuario que se encarga de presentar una parte o todo el modelo para el usuario y permite al usuario modificar su contenido a través de una interfaz de usuario. La vista sólo implementa la interfaz de usuario lógica y las relaciones con la lógica de negocio recaén en el presenter.
- SmartPart: es un control de usuario con el atributo [SmartPart] aplicado dejando de forma opcional la implementación de ISmartPartInfoProvider que proporciona información adicional acerca de sí misma, como un título o una descripción.
- Presenter: Es una clase que implementa la lógica de modificación de un modelo. Cada módulo, tiene su presenter y una presenter puede usarse des de varias vistas.
- ObjectBuilder: Componente fundamental de CAB, que actúa como una fábrica para crear objetos específicos que requieren un constrictor o que necesitan funciones específicas, como la instanciación automática y que depende de la inicialización de objetos al crear instancias.
- DependencyInjection: Es un patrón que permite a una fábrica crear automáticamente o inicializar las propiedades o los miembros de objetos con objetos de su cargo. ObjectBuilder le proporciona esta funcionalidad y sus dependencias vendrán descritas en un fichero de configuración.
- Bussiness Module: Módulos de negocio, esencialmente proyectos DLL que contienen una unidad del negocio junto con sus vistas. Cada módulo de negocio, contiene un WorkItemController principal.
- Foundation Module: No contiene ni vistas ni WorkItems. Se utilizan para contener servicios globales que se usan en todos los módulos como por ejemplo Acceso a Datos, Logging, Seguridad...
Ambos, Bussiness y Foundation Module, contienen una clase Module que hereda de ModuleInit con un método Load para que CAB los pueda cargar.
Principalmente, SCSF, utiliza el patrón Modelo - Vista - Presentador (MVP) entre otros. Una vista (View), gestiona los controles en el formulario y cede la responsabilidad de la lógica de la UI al presentador a través de los eventos del cliente. El presentador (presenter), contiene la lógica capaz de responder estos eventos y gestiona el estado de la vista a través del modelo (Module) que tiene las entidades empresariales (datos). El presentador, no hace una referencia directa de la vista, si no que hace referencia a una interfaz para la vista (IView) que se encarga de los cambios de estado.
¿Y porqué trabajar de este modo? Como tenemos separado la UI de la lógica de la pantalla, podemos portar la aplicación a diferentes tipos de presentación sea WebClient, WPF Client, Silverlight Client... y además este modelo nos permite probar todo el funcionamiento de la pantalla sin tener UI, solo haciendo pruebas sobre el presentador.
Veremos poco a poco nuevos conceptos que iremos aprendiendo a lo largo de las diferentes entregas. Para empezar debereís instalar el smart client software factory dónde en el enlaze viene muy bien explicado. Ahora se debe actualizar, esto se debe a que para que os compile, se debía modificar el proyecto... Lo teneís aquí, y aunque no es oficial, funciona perfectamente aplicando los cambios recomendados por Microsoft.
Hasta aquí la teoría. Ahora, nos toca la parte más divertida, pero, será en la segunda entrega dónde usemos lo anterior en un proyecto real.
Espero vuestras dudas o comentarios ;)