Der Composite UI Application Block, kurz CAB, ist ein großartiges und beliebtes Framework für Enterprise Applikationen, welches Microsoft über seine Patterns & Practices Group kostenlos zur Verfügung stellt.
Aus eigener leidvoller Erfahrung weiss ich, wie kniffelig es ist, den Einstieg in dieses Framework zu schaffen. Daher will ich in diesem Blog meine Erfahrungen mit CAB / SCSF teilen.
Dieser erste Artikel soll die wichtigsten Begriffe kurz erklären und kann vielleicht dem einen oder anderen zum Nachschlagen dienen.
Module
… sind Assemblies, die einen oder mehrere UseCases für die Anwendung enthalten und vom CAB Framework zur Laufzeit zur Anwendung hinzugefügt werden. Der Eintrittspunkt ist hierbei die Load()-Methode der ModuleInit-Klasse, welche bereits vom Template erstellt wird.
WorkItems
... sind Objekte über deren Properties der Zugriff auf Services, Events und andere WorkItems der WorkItem-Hierarchie möglich ist. Seit der Einführung des SCSF (Smart Client Software Factory, ein Aufsatz auf das klassische CAB Framework) sollten keine weiteren eigenen Ableitungen der WorkItem-Klasse erstellt werden. Stattdessen sollten überall ControlledWorkItems verwendet werden (eine sealed-Klasse aus dem CAB Framework), welche jeweils zusammen mit den dazugehörigen WorkItemControllern erzeugt werden. UseCase-Logik wird im jeweiligen WorkItemController des WorkItems ausprogrammiert.
WorkItemController
... sind die Klassen, in denen wir unsere UseCase-Logik ausprogrammieren. WorkItemController halten alles, was zum UseCase gehört (Datenobjekte, Presenter, Views etc.) und regeln das Zusammenspiel dieser Elemente. Jeder WorkItemController hat ein WorkItem-Property über das er Zugriff auf die CAB-Infrastruktur hat.
Der WorkItemController ist nicht zu verwechseln mit dem Controller aus Model-View-Controller (s. unten). Der WorkItemController kann zwar in Einzelfällen die Aufgabe des Controllers mit übernehmen, ist aber prinzipiell davon abzugrenzen.

(Grafik zur Verdeutlichung der Hierarchischen Struktur von WorkItems und dazugehörigen WorkItemControllern)
Services
... sind ganz normale .NET Klassen, die eine Funktionalität anbieten, die quer durch unsere Anwendung zur Verfügung gestellt werden soll. Üblicherweise sind Services dem Rest der Anwendung nur über das Interface bekannt, welches sie implementieren.
Dependency Injection
... ist ein Mechanismus um lose Koppelung zwischen zusammenarbeitenden Klassen zu erreichen. Infolgedessen kennen sich die konkreten Implementierungen der zusammenarbeitenden Klassen gegenseitig nur über allgemein zugängliche Interfaces und sind somit austauschbar.
In der Dependency Injection ist das Dependency Injection Framework (in unserem Fall CAB ) dafür zuständig, die passenden konkreten Instanzen zu den gewünschten Interfaces bereitzuhalten (oder bei Bedarf zu erzeugen) und in die beteiligten Klassen zu „injizieren“.
Im CAB werden die Stellen, in die Instanzen injiziert werden sollen über die Attribute [ServiceDependency], [CreateNew] oder [ComponentDependency] gekennzeichnet. Am üblichsten sind dies Properties mit einem public Setter. Alternativ steht Dependency Injection über den Konstruktor (in Form von injizierten Konstruktorparametern) zur Verfügung.
Dependency Injection wird im CAB dann ausgelöst, wenn ein Objekt mit oben beschriebenen Attributen in eine Collection auf einem WorkItem eingefügt wird. Die Instanzen, dabei injiziert werden, werden von dem WorkItem abgefragt, das die Dependency Injection ausgelöst hat.
SmartParts
… werden Benutzeroberflächen-Controls im CAB Framework genannt, tatsächlich sind dies in der Regel schlicht Windows Forms Controls. SmartParts müssen keine bestimmte Basisklasse oder Interface implementieren, auch die Angabe des Attributes [SmartPart] ist optional und macht in den wenigsten Fällen einen Unterschied.
WorkSpaces
... sind die Platzhalter in der Benutzeroberfläche, in denen SmartParts dargestellt werden sollen. WorkSpaces haben gemein, dass sie das Interface IWorkspace implementieren.
ProfileCatalog
... ist eine XML-Datei im Bin-Verzeichnis, in der alle Module eingetragen sind, die CAB beim Start laden soll. (Siehe auch: Detailbeschreibung Module)
ModuleInit
... ist eine Klasse, die als Eintrittspunkt eines Modules fungiert. Die ModuleInit-Klasse sollte je Modul nur einmal auftauchen sollte. Standardmäßig kann sie in der Form, in der sie bereits vom Projekt Template erzeugt wird verwendet werden und muss nicht weiter abgeändert werden.
ModuleController
... ist der WorkItemController des ersten WorkItems (quasi des ModuleRootWorkItems) eines Modules. Der Rumpf dieser Datei wird bereits vom Project Template angelegt. Der ModuleController wird in der Load-Methode der ModuleInit-Klasse erzeugt und ausgeführt.
Shell
... ist die Hostanwendung samt Benutzeroberfläche, in welche die einzelnen Module geladen werden. Die Shell wird in der WorkItem-Hierarchie über das RootWorkItem repräsentiert.
UIExtensionSites
... sind Platzhalter auf der Benutzeroberfläche, die von Modulen erweitert werden können. Typische Beispiele hierfür sind Toolbars oder die RibbonPage eines RibbonControls.
Commands
... sind lose gekoppelte Events ohne Übergabeparameter. Das auslösende und das reagierende Objekt müssen einander nicht kennen. Die „Verkabelung“ geschieht automatisch durch das CAB Framework. Commands gehören nicht zum Event-Mechanismus (EventPublication und EventSubscription) sondern stellen eine einfachere Alternative dazu dar.
EventPublication
... ist die auslösende Seite des Event-Mechanismus im CAB. Der EventPublication wird über eine Stringkonstante ein eindeutiger Namen zugewiesen. Das CAB Framework sorgt dann dafür, dass all jene EventSubscriptions, die sich unter dem selben Namen registriert haben, ausgeführt werden, sobald die EventPublication gefeuert wird. Die gängigste Art, EventPublications zu registrieren, ist das [EventPublication] Attribut über ein herkömmliches .NET Framework-Event zu schreiben.
EventSubscription
... ist die reagierende Seite des Event-Mechanismus im CAB. EventSubscriptions werden erzeugt, indem Methoden mit dem [EventSubscription] Attribut versehen werden. Die Methodensignatur muss derjenigen entsprechen, die auch von Eventhandler-Methoden der dazugehörigen .NET Events erwartet würde.
Model-View-Controller bzw. Model-View-Presenter

Model
... ist ein Begriff aus dem Pattern Model-View-Controller (oder Model-View-Presenter) und meint das Datenmodell, das durch eine View dargestellt und / oder verändert werden soll. In DML2 ist das Model in der Regel durch die XPO Datenklassen vertreten.
View
... ist ein Begriff aus dem Pattern Model-View-Controller (oder Model-View-Presenter) und steht für die Benutzeroberfläche, die den Inhalt des Datenmodells darstellen und / oder für den Benutzer bearbeitbar machen soll.
Die View hat in der Ausprägung von Model-View-Presenter, die im CAB / SCSF empfohlen wird, eine direkte Referenz auf das Presenter-Objekt, über welche die View (in Reaktion auf Events oder Benutzerinteraktion) Methoden des Presenters ausführt (z.B. Presenter.Refresh(); ). Die View hat in dieser Implementierung überdies keine direkte Referenz auf das Model. Die empfohlene Vorgehensweise ist weiterhin, dem Presenter seine View nur über ein Interface bekannt zu geben.
Presenter
... ist ein Begriff aus dem Pattern Model-View-Presenter (MVP ) und ist als vermittelnde Klasse zwischen Datenmodell und Benutzeroberfläche gedacht. In CAB erben Presenter von Presenter mit dem generischen Typparameter TViewInterface, und stellen dadurch automatisch ein Property „View“ vom Typ TViewInterface zur Verfügung.
Im Gegensatz zu Model-View-Controller (MVC ) ist in MVP der Presenter dafür zuständig die View direkt upzudaten. In MVC hingegen ändert der Controller das Model, welches die View infolgedessen über ein Event von der Veränderung benachrichtigt.
Controller
... ist ein Begriff aus dem Pattern Model-View-Controller (MVC) und steht für eine Klasse, die als Vermittler zwischen Datenmodell und Benutzeroberfläche gedacht ist.
In CAB / SCSF ist keine Basisklasse für den Controller vorhanden. Obwohl eine Implementierung von Model-View-Controller in CAB problemlos machbar ist, wird das Pattern Model-View-Presenter in der Ausprägung „passive View“ empfohlen. Der Controller aus MVC ist nicht zu verwechseln mit dem WorkItemController oder dem ModuleController.