Estos días he estado revisando un programilla de ejemplo que empecé a principios de año ( aprovechando que me quede en paro
jeje ) y que ha estado parado desde entonces … si es que soy un vago juas
La aplicación iba a ser un port de una aplicacion vieja a .NET ( que ha quedado en nada en cuanto he vuelto a currar jajaja ).
Una de las cosas en las que tenia más dudas era en como implementar la UI … habia algo claro tendría que usar el patrón MVC ( model view controller ) o el MVP ( model view presenter ).
Como tras leer un poco del tema quedó claro que iba a ser un curro de chinos y no estaba el tema para perder el tiempo … anduve buscando por inet hastq ue di con el Composite UI Application Block (en adelante CAB a secas para abreviar), dando gracias que estoy desde entonces …
El CAB ofrece la infraestructura necesaria para el desarrollo de Smart Clients ( estos de Microsoft ya no saben que nombre ponerle a las cosas … )
En su momento no me dio tiempo a ver mucho pero … algunas de las cosas interesantes que tiene son:
· Un Shell. Es el punto de entrada principal de la aplicación la implementación del sehll se divide en varias partes:
- Un formulario. En donde mostrar la UI de la aplicación ( menus, barras de herramientas, las vistas de la aplicación , etc … ) y al que se debe añadir un o varios WorkSpaces para mostrar las vistas de la aplicación ( Smart Parts ). El CAB viene con varias implementaciones de Workspaces, en el caso del ejemplo que sigue se utiliza una implementación especifica ( TabbedDocumentWorkspace ).
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Printing; using System.Globalization; using System.Text; using System.Windows.Forms; using Microsoft.Practices.CompositeUI; using Microsoft.Practices.CompositeUI.Services; using Microsoft.Practices.ObjectBuilder; using Microsoft.Practices.CompositeUI.Commands; using Microsoft.Practices.CompositeUI.EventBroker; namespace Cab.Test.Shell { public partial class ShellForm : System.Windows.Forms.Form { #region · Fields · private WorkItem workItem; private IWorkItemTypeCatalogService workItemTypeCatalog; #endregion #region · Constructors · public ShellForm() { InitializeComponent(); } [InjectionConstructor] public ShellForm(WorkItem workItem, IWorkItemTypeCatalogService workItemTypeCatalog) : this() { this.workItem = workItem; this.workItemTypeCatalog = workItemTypeCatalog; // Inicializamos el workspace this.workItem.Workspaces.Add(new TabbedDocumentWorkspace(), "contentWorkspace"); } #endregion } }
En el constructor que toma parametros se utiliza un atributo que hará que se le pasen los parámetros utilizando dependency injection.
- Un WorkItem. Para implementar el caso de uso del Sehll. Este será el RootWorkItem de la aplicación.
using System; using Microsoft.Practices.CompositeUI; namespace Cab.Test.Shell { public class ShellWorkItem : WorkItem { } }
- Una implementación de FormShellApplication. Esta será la clase encargada de cargar la aplicación ( shell, modulos, etc … )
using System; using System.Text; using System.Windows.Forms; using Microsoft.Practices.CompositeUI; using Microsoft.Practices.CompositeUI.WinForms; namespace Cab.Test.Shell { public class ShellApplication : FormShellApplication<ShellWorkItem, ShellForm> { #region · Singleton Instance · public static readonly ShellApplication Instance = new ShellApplication(); #endregion #region · Constructors · private ShellApplication() : base() { } #endregion #region · Protected Methods · protected override void AfterShellCreated() { base.AfterShellCreated(); // Registro de los menus barras de herramientas, etc ... ( RootWorkItem.UIExtensionSites.RegisterSite(UIExtensionConstants.MainMenuStrip, Shell.MainMenuStrip); RootWorkItem.UIExtensionSites.RegisterSite(UIExtensionConstants.MainToolStrip, Shell.MainToolStrip); } protected override void AddServices() { base.AddServices(); // Añadir los servicios que deban estar disponibles // RootWorkItem.Services.Add(typeof(...), xxx); } #endregion #region · Unhandled Exception · public override void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) { // Procesar la exceción } #endregion } }
Por último hay que ejeuctar la aplicacón para lo que bastará hacer esto:
ShellApplication.Instance.Run();
· WorkItems. Que ( sino me equivoco ) sirven para implementar los casos de uso, utilizando MVC/MVP, en donde:
-
- Modelo. Se representa en el estado del WorkItem.
- Vista. Los WorkItems pueden tener asociadas una o mas vistas.
- Controlador/Presentador. Cada vista tendrá asociado un controlador/presentador.
· Event Broker ( En mi opinion casi casi lo mejor de todo lo que he visto del CAB hasta ahora … sencillamente acojonante por las posibilidades que tiene )
Se pueden utilizar utilizando atributos o por código.
Un ejemplo utilizando atributos:
[EventPublication("event://ViewStateChanged", PublicationScope.WorkItem)] public event EventHandler<ViewStateChangedEventArgs> ViewStateChanged;[EventSubscription("event://ViewStateChanged", Thread = ThreadOption.UserInterface)] public void ViewStateChanged(object sender, ViewStateChangedEventArgs e) { SmartPartControlsUpdater.UpdateSmartPartControls(this, e.NewState); }
No es necesario hacer nada más, el propio sistema se encarga ( gracias al ObjectBuilder que es un framework de Dependency Injection ) de asociar el elemento que publica el evento ( un mismo evento puede ser publicado por más de un elemento ) con los suscriptores que se hayan configurado.
· Un Command Manager. Sino me equivoco es una implementación del patrón Command. Útil cuando un comando determinado se puede ejecutar desde variso sitios distintos ) por ejemplo una opción de menú y un botón deun abarra de herramientas.
Un manejador para un comando ( por ejemplo para la opción de menú que permite salir de la aplicación ) se definiría asi:
[CommandHandler("FileExit")] public void OnFileExit(object sender, EventArgs e) { // Procesar el comando }
0 Respuestas a “Composite UI Application Block”