---
title: clsPreferences
summary: API reference for clsPreferences.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-08-17
library: SAIF.Presentation
reference_type: package
---

# clsPreferences

`clsPreferences` is the sole public type in `SAIF.Presentation` and the library's entire reason for existing: a per-user, per-application preference façade consumed by `SAIF.Presentation.Web.Core.Infragistics111` and `SAIF.Presentation.Web.Controls.V2.Menu` to persist UI state such as Infragistics grid column order, widths, sort order, and size. On construction it opens an Oracle data portal (`clsMSOracleDataLayer`, user `CLM`) and eagerly loads every stored preference for the effective user through `SAIF.Framework.Preferences.PreferenceData.GetPreferencesForUser`; all subsequent reads and mutations are served from memory, and `Save()` is the only path back to persistence. The type is marked `<Serializable()>` even though it holds a live data-layer reference.*

## Purpose
- Provide indexed, scope-aware read access to a user's preferences ([BR-PRES-011](../../business-rules.md#br-pres-011-preference-record-identified-by-application-and-page)).
- Provide mutators (`Add`, `Remove`, `Clear`, `Delete`) that update the in-memory preference set without touching the database until `Save()` is called ([BR-PRES-019](../../business-rules.md#br-pres-019-mutations-are-in-memory-until-save)).
- Serialize and persist preference changes through the framework preference service, scoped to the store's current application ([BR-PRES-020](../../business-rules.md#br-pres-020-save-persists-only-the-current-applications-records)).

## Context
- Namespace: `SAIF.Presentation`
- Assembly/package: `SAIF.Presentation` (packaged into `SAIF.BOF.Presentation.Web.Infragistics111.nuspec` as `SAIF.Presentation.Web.Infragistics111.dll`)

## Public members
| Member | Signature | Purpose |
| --- | --- | --- |
| `New` | `New(inUserID As String, inApplication As String)` | Creates the store for a user and application and immediately loads that user's existing preferences into memory via `Initialize` → `Load` ([BR-PRES-004](../../business-rules.md#br-pres-004-all-preferences-loaded-eagerly-on-construction)). |
| `New` | `New(userID As String, application As String, preferencesRootDirectory As String)` | Same as the two-argument constructor; `preferencesRootDirectory` is accepted but **ignored** — it delegates to the same `Initialize` path. |
| `Item` | `Item(inKey As Object) As Object` (default property) | Looks up a value at page scope for the current application and derived page; returns `Nothing` when the key or record is not found ([BR-PRES-008](../../business-rules.md#br-pres-008-only-pagelevel-scope-binds-to-a-page)). |
| `Item` | `Item(inKey As Object, inScope As PrefScope) As Object` (default property) | Looks up a value at the specified scope for the current application, resolving the page key from `scope` before the lookup. |
| `Item` | `Item(inApplication As String, inPage As String, inKey As String) As Object` (default property) | Looks up a value across explicit application/page/key values, lower-casing all three and treating `Nothing` as an empty string, bypassing scope resolution ([BR-PRES-012](../../business-rules.md#br-pres-012-explicit-three-argument-lookup-matches-lower-cased-fields)). |
| `Count` | `ReadOnly Property Count As Integer` | Returns the number of loaded `Preference` records (application/page bags), not the number of individual key/value items. |
| `OverridePage` | `Property OverridePage As String` | Sets or gets the page name used for non-web callers; when non-empty it takes precedence over the reflected call-stack page name ([BR-PRES-010](../../business-rules.md#br-pres-010-non-web-page-name-derived-from-override-or-call-stack)). Desktop callers must set this before calling `Save()` for page-scoped values to persist under a stable key. |
| `Add` | `Sub Add(inKey As Object, inValue As Object)` | Upserts a preference item at the default (`PageLevel`) scope; creates the backing `Preference` record if it does not exist yet ([BR-PRES-013](../../business-rules.md#br-pres-013-adding-a-preference-creates-a-missing-record)). |
| `Add` | `Sub Add(inKey As Object, inValue As Object, inScope As PrefScope)` | Upserts a preference item at the specified scope; replaces the value if the key already exists by removing then re-adding it, storing the value as `inValue.ToString()` ([BR-PRES-014](../../business-rules.md#br-pres-014-adding-an-existing-key-replaces-its-value), [BR-PRES-015](../../business-rules.md#br-pres-015-preference-values-stored-as-strings)). |
| `Remove` | `Sub Remove(inKey As Object)` | Removes one preference item at page scope for the current application/page; a missing key is a silent no-op ([BR-PRES-016](../../business-rules.md#br-pres-016-removing-an-absent-key-is-a-no-op)). |
| `Remove` | `Sub Remove(inKey As Object, inScope As PrefScope)` | Removes one preference item at the specified scope. |
| `Clear` | `Sub Clear(inScope As PrefScope)` | Empties every item in the `Preference` record for the current application and the scope's resolved page key ([BR-PRES-017](../../business-rules.md#br-pres-017-clear-empties-all-items-in-a-scopes-record)). |
| `Delete` | `Sub Delete()` | Empties the items of **every** loaded `Preference` record for the user, across all applications and pages ([BR-PRES-018](../../business-rules.md#br-pres-018-delete-empties-every-loaded-record)). |
| `Save` | `Function Save() As Boolean` | Serializes and persists every in-memory `Preference` record whose `ApplicationName` matches the current application through `PreferenceData.SavePreferences`, wrapping any failure in an `ApplicationException` ([BR-PRES-023](../../business-rules.md#br-pres-023-persistence-always-routed-through-preferencedata), [BR-PRES-024](../../business-rules.md#br-pres-024-persistence-failures-wrapped-in-applicationexception)). The return value is **always `False`**, even on success, because the local `result` is never assigned `True` — a verified defect. |

## Behavioral notes
- Every constructor path opens a live Oracle data-layer connection and loads all of the user's preferences (all applications, all pages) eagerly — there is no lazy loading or caching across instances ([BR-PRES-004](../../business-rules.md#br-pres-004-all-preferences-loaded-eagerly-on-construction)).
- The effective user identity used for load and save is `IDataPortalInfo.UserID` from the data portal, not the `inUserID` constructor argument ([BR-PRES-003](../../business-rules.md#br-pres-003-effective-user-identity-comes-from-the-data-portal)).
- All keys are lower-cased on every keyed operation, making preference keys effectively case-insensitive ([BR-PRES-007](../../business-rules.md#br-pres-007-preference-keys-are-case-insensitive)).
- A private `FormatKey` method builds `application~page~key` composite keys but is **not called** by any live code path — the current lookup path filters the `Preference` list by `ApplicationName` / `Pagename` instead. It is dead but compiled code.*
- `Save()` declares an unused `System.Xml.XmlTextWriter` local (`PrefWriter`), and its trailing `clsLogTrace.MethodEnd()` call is unreachable because it follows `Return result`.*

## Constraints and usage notes
- Callers must call `Save()` after any `Add` / `Remove` / `Clear` / `Delete` call, or the mutation is lost at the end of the request ([BR-PRES-019](../../business-rules.md#br-pres-019-mutations-are-in-memory-until-save)).
- Callers cannot rely on `Save()`'s boolean return value to detect success — it always returns `False`. Persistence failure is signaled only by a thrown `ApplicationException`.
- Non-web (desktop) callers must set `OverridePage` before relying on page-scoped preferences, otherwise the page key is derived by reflecting the call stack, which is brittle to refactors.*

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

## Sources
- `SAIF.Presentation/clsPreferences.vb`
