The implementation of LitwareHR-SC is fairly straight forward. Especially if you are familiar with CAB and SC-SF. When you open LitwareHR-SC solution you will see a number of projects:
The most interesting code is under of course Litware.HR. All main logic is contained in this assembly: this is where all views, presenters, core services and generally speaking all "business logic" is.
Being a CAB based solution, LitwareHR-SC consists of a single "CAB module" which is hosted by a Shell. A default shell is provided, but you can re-host the module anywhere if you provide the logical workspaces the module expects.
There are roughly 3 layers implemented in Litware.HR as illustrated in Figure 1.
Figure 1: LitwareHR Smart Client Architecture
The app makes extensive use of CAB Events for notification of important changes such as: connectivity changes, branding and style changes (new logo), meta-data changes, etc. Most events are published by the Services and consumed by either other Services, Presenters and the Shell. This is the way the status bar in the Shell changes from "Online" to "Offline" for example.
Look for any [EventPublication] attribute in the code.
The best way of understanding how the app is initialized is by looking at the Run method in the ModuleController class of Litware.HR. This is the "main" function for a CAB module generated by the SC-SF.
Placing a few breakpoints and stepping over the code here will give you an idea of how things are wired together and what depends on what.
Almost all services are built with a similar pattern:
For example:
Figure 2: Tenant Branding Service code snippet
In this case, when added to the (root) WorkItem, the TenantBrandingService will be initialized with 3 dependent services: PresentationService, ConnectionMonitor and the AuthenticationService. It also publishes 2 events:
The Recruiting Service is the main business logic service. You will notice it has LitwareHR semantics (e.g. Open Positions, Get Positions, etc) but above all this is where the switching logic is for retrieving data either from the on-line services or the local store depending on network availability. The strategy followed in the app is to always try to interact with the on-line services and fallback to the offline store if that fails. There's plenty of room for more advanced strategies like using the offline store as a cache if the requests are received within a short time window, etc.
The meta-model (entities & views definitions) are updated every time connectivity is a change in the connectivity status. This means that each time you disconnect & connect the data & views schemas are retrieved from LitwareHR on-line services and compared against the local ones. If there's any difference an update is done and the corresponding event is raised.
Branding (exemplified through the header logo) is updated "real-time". Under the hood, the branding service polls for changes in the configured style and if it detects changes against the current one, it will download the new logo. All this is done asynchronously so the UI remains responsive throughout all the process.
The next articles will drill-down on specifics aspects of the solution that are interesting.