---
title: SAIF.Presentation architecture
summary: Architectural responsibilities, boundaries, and interaction patterns.
status: draft
owner: SAIF Documentation Team
last_reviewed: 2026-08-17
library: SAIF.Presentation
reference_type: package
---

# SAIF.Presentation architecture

`SAIF.Presentation` is a single-purpose presentation-tier library that provides a per-user, per-application/page preference (settings) store. It contains one functional class, `clsPreferences` (plus its supporting `PrefScope` enum), which mediates between calling UI code (web pages or Windows Forms) and the SAIF BOF data-access layer, delegating all persistence to `SAIF.Framework.Preferences.PreferenceData`.

## Responsibilities
- Cache all `Preference` groups for the authenticated portal user in memory on construction (`Load()` → `PreferenceData.GetPreferencesForUser`), scoped by application name and page name.
- Provide scoped read/write access to preference key-value pairs via `PrefScope.AppLevel`, `PrefScope.PageLevel`, and `PrefScope.WebLevel`, exposed through the `Item` indexer and the `Add`/`Remove`/`Clear`/`Delete` members.
- Resolve the "current page" identity using a dual strategy: parsing `System.Web.HttpContext.Current.Request.Path` in web contexts, or falling back to an explicit `OverridePage` value or `System.Diagnostics.StackTrace` reflection in non-web contexts*.
- Persist in-memory preference changes back to the Oracle-backed `PreferenceData` store on explicit `Save()` calls, serializing each preference group's items to JSON via `JavaScriptSerializer`.
- Resolve the Oracle connection target for its own persistence needs through the `SAIF.Framework.Common` environment-service abstraction (`AppGlobal.EnvironmentService.GetConfigSetting(EnvironmentConfigKeys.OracleDatabase)`), rather than reading configuration locally (see [Configuration](configuration.md)).

## Component boundaries
- `clsPreferences`: the sole public service boundary of this library — an in-memory preference cache plus a thin persistence-orchestration layer. It owns no SQL and implements no `IBusinessCriteria` pattern itself; all durable storage is delegated to the external `PreferenceData` type.
- `PrefScope`: a public enum (`AppLevel`, `PageLevel`, `WebLevel`) that defines the boundary at which a preference key is stored/retrieved; it is the contract consumers use to select scoping behavior on every `Item`/`Add`/`Remove`/`Clear` call.
- External boundary — `SAIF.Framework.Preferences.PreferenceData`/`Preference`: the actual persistence layer (Oracle-backed), consumed but not defined in this library; its internal SQL/BOF implementation is out of scope for this library**.
- External boundary — `SAIF.Framework.Common` (`clsMSOracleDataLayer`, `AppGlobal.EnvironmentService`, `EnvironmentConfigKeys`): supplies the Oracle data-portal context (`IDataPortalInfo`) and configuration resolution used by `Load()`.
- Cross-cutting boundary — `clsLogTrace` (from `SAIF.BOF.Framework`): method-entry/exit tracing wrapped around `Remove()` and `Save()`.

## Interaction model
- Consumers (web pages, Windows Forms, or other SAIF.Presentation.* libraries) construct a `clsPreferences` instance, supplying a user ID and application name; construction eagerly loads all preference groups for the authenticated data-portal user (`m_DPI.UserID`), not the constructor's `inUserID` parameter*.
- Reads use the `Item` indexer (three overloads) to fetch a value scoped by application/page/key entirely from the in-memory `_Preferences` list — no database round-trip occurs on read.
- Writes (`Add`, `Remove`, `Clear`, `Delete`) mutate only the in-memory list; nothing is written to the database until the consumer explicitly calls `Save()`.
- `Save()` persists only the preference groups whose `ApplicationName` matches the current `m_Application`, via `PreferenceData.SavePreferences`; its `Boolean` return value is not a reliable success indicator because of a dead-code path that always returns `False`*.
- This library is consumed as a same-repo `<ProjectReference>` (its `.vb` source, not a compiled binary, is recompiled by each consumer per the package's nuspec) by four other libraries in this repository: `SAIF.Presentation.Web.Core.Infragistics103`, `SAIF.Presentation.Web.MVC` (`clsModelBase`, exposing a `Preferences` property backed by `clsPreferences`), `SAIF.Presentation.Web.Controls.V2.Menu` (`SAIFMenu`, using `PrefScope.AppLevel` to persist a `SHOWAPPS` menu preference), and `SAIF.Presentation.Web.Controls.AJAX.Infragistics103` (`InfragisticsGridCustomizer`, resolving a `clsPreferences` instance via `BindingUtility.GetObject`).

## Architecture diagram
The following diagram shows how consumer libraries obtain and use the `clsPreferences` service, and how it delegates persistence downstream.

```mermaid
flowchart TD
	A[SAIF.Presentation.Web.MVC<br>clsModelBase] --> D[clsPreferences]
	B[SAIF.Presentation.Web.Controls.V2.Menu<br>SAIFMenu] --> D
	C[SAIF.Presentation.Web.Controls.AJAX.Infragistics103<br>InfragisticsGridCustomizer] --> D
	D --> E[PreferenceData<br>SAIF.Framework.Preferences]
	D --> F[clsMSOracleDataLayer<br>SAIF.Framework.Common]
	F --> G[AppGlobal.EnvironmentService<br>GetConfigSetting]
	E --> H[(Oracle DB<br>DB user CLM)]
```

## Sequence diagram
The following diagram shows the primary construct-read-write-save sequence for a preference consumer.

```mermaid
sequenceDiagram
	participant Consumer
	participant clsPreferences
	participant PreferenceData
	participant OracleDB
	Consumer->>clsPreferences: New(userId, application)
	clsPreferences->>PreferenceData: GetPreferencesForUser(m_DPI.UserID)
	PreferenceData->>OracleDB: Query preferences (CLM schema)
	OracleDB-->>PreferenceData: Preference rows
	PreferenceData-->>clsPreferences: List(Of Preference)
	Consumer->>clsPreferences: Add(key, value, scope)
	Note over clsPreferences: In-memory mutation only
	Consumer->>clsPreferences: Save()
	clsPreferences->>PreferenceData: SavePreferences(app, page, userId, json)
	PreferenceData->>OracleDB: Persist preference JSON
	clsPreferences-->>Consumer: Boolean (always False)*
```

## Design constraints
- The library has zero `<ProjectReference>` dependencies of its own — it is a leaf/foundational presentation utility, but four other libraries in this repository depend on it via project reference, so its public surface (`clsPreferences`, `PrefScope`) is a de facto internal contract.
- All persistence is hard-wired to Oracle under the fixed DB user `"CLM"` (`m_DBUserName`), independent of which consuming application constructs the instance — this couples every consumer to the same database schema/user context.
- The only externalized configuration touchpoint is the Oracle connection setting `EnvironmentConfigKeys.OracleDatabase`, resolved via `AppGlobal.EnvironmentService.GetConfigSetting`; the library defines no `App.config`/`Web.config` and reads no `AppSettings` directly.
- `Save()`'s boolean return value cannot be trusted to detect failure (dead code after `Return result`); only a thrown `ApplicationException` signals a save error*.
- The 3-argument constructor's XML documentation describes file-based storage via a `preferencesRootDirectory` parameter, but the parameter is accepted and ignored — the live implementation always loads from the Oracle-backed `PreferenceData`, so the documented and actual behavior diverge*.
- This project's compiled binary is not what ships in the `SAIF.BOF.Presentation.Web.Infragistics103` NuGet package; only its `.vb` source is bundled (per the root `.nuspec`) for consumers to recompile alongside `SAIF.Presentation.Web.Core.Infragistics103`'s compiled output*.

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Configuration](configuration.md)
- [API reference](api/index.md)

## Sources
- SAIF.Presentation\clsPreferences.vb
- SAIF.Presentation\SAIF.Presentation.vbproj
- SAIF.Presentation\packages.config
- SAIF.Presentation.Web.MVC\clsModelBase.vb
- SAIF.Presentation.Web.Controls.V2.Menu\SAIFMenu.vb
- SAIF.Presentation.Web.Controls.AJAX.Infragistics103\InfragisticsGridCustomizer.vb
- SAIF.BOF.Presentation.Web.Infragistics103.nuspec
