SAIF.Framework.Preferences architecture¶
SAIF.Framework.Preferences is a small, self-contained data-access library that persists per-user application/page preference blobs. It consists of exactly two classes — the Preference DTO and the PreferenceData data-access class — and reads/writes a single Oracle table, USER_PREFERENCE, via inline SQL rather than the framework's standard business-object pattern.
Responsibilities¶
- Provide a data-access surface for reading a single preference blob (
GetPreferences), reading all preferences for a user (GetPreferencesForUser), and upserting/deleting a preference (SavePreferences). - Represent one saved preference record as a simple DTO (
Preference), carrying application name, page name, preference ID, and a deserialized key/value item dictionary. - Normalize and scope preference identity by application name, user ID (lower-cased), and optional page name.
- Serialize/deserialize the stored preference payload as JSON (
PREFERENCE_TEXT) usingJavaScriptSerializer.
Component boundaries¶
Preference(SAIF.Framework.Preferences\Preference.cs): plain data-transfer object. Public fieldsPreferenceId,ApplicationName,Pagename,PreferenceItems; no behavior beyond a parameterless constructor.PreferenceData(SAIF.Framework.Preferences\PreferenceData.cs): the sole data-access class. Public methodsGetPreferences,GetPreferencesForUser,SavePreferences; private helpersInsertPref,UpdatePref,DeletePref,DoesPrefExist. Constructed with an injectedIDataPortalInfo(DPIfield) supplied by the caller.- External boundary —
SAIF.Framework(built fromSAIF.Framework.Core): suppliesIDataPortalInfo,SqlHelper.ResultSetQuery,SqlHelper.ScalarQuery<T>,SqlHelper.NewParm, andclsResultSet.DataRow. This library has no<ProjectReference>toSAIF.Framework.Core; it references the compiledSAIF.Framework.dllvia aHintPathbinary reference. - Database boundary — USER_PREFERENCE (Oracle), the single table this library reads and writes, keyed via the
USER_PREFERENCE_SEQsequence.
Interaction model¶
- Host applications construct
PreferenceDataby supplying anIDataPortalInfoinstance; this library does not resolve its own connection/portal context. GetPreferencesbuilds a parameterized SELECT scoped byUSER_ID/APP_NAME/optionalPAGE_NAME(see SQL-002), executes it viaSqlHelper.ResultSetQuery, and returns the rawPREFERENCE_TEXTstring (orstring.Emptyif no row matches).GetPreferencesForUserselects all rows for aUSER_ID(see SQL-003), builds onePreferenceobject per row, and deserializes non-emptyPREFERENCE_TEXTJSON intoPreferenceItemsviaJavaScriptSerializer.SavePreferencesis the single write entry point: it branches toDeletePref(see SQL-006) whenpreferenceTextis empty/whitespace, otherwise checksDoesPrefExist(see SQL-007) and dispatches toUpdatePref(see SQL-005) orInsertPref(see SQL-001 and SQL-004) accordingly. All three internal operations execute viaSqlHelper.ScalarQuery<int>.- There is no application/UI layer code in this library — it is a reusable component intended to be consumed by host applications.
Architecture diagram¶
The following diagram shows the high-level component interactions for this library.
flowchart TD
Caller["Host application"] --> PD["PreferenceData"]
PD --> DTO["Preference (DTO)"]
PD --> DPI["IDataPortalInfo<br>(injected by caller)"]
PD --> SqlHelper["SqlHelper.ResultSetQuery /<br>SqlHelper.ScalarQuery<T><br>(SAIF.Framework)"]
SqlHelper --> DB[("USER_PREFERENCE<br>(Oracle)")]
Sequence diagram¶
The following diagram shows the primary save (upsert/delete) request sequence.
sequenceDiagram
participant Caller as Host application
participant PD as PreferenceData
participant SQL as SqlHelper
participant DB as USER_PREFERENCE (Oracle)
Caller->>PD: SavePreferences(appName, pageName, userId, preferenceText)
alt preferenceText is empty/whitespace
PD->>SQL: DeletePref (ScalarQuery)
SQL->>DB: DELETE
else preferenceText present
PD->>SQL: DoesPrefExist (ScalarQuery)
SQL->>DB: SELECT COUNT(*)
DB-->>SQL: count
alt row exists
PD->>SQL: UpdatePref (ScalarQuery)
SQL->>DB: UPDATE
else no row
PD->>SQL: InsertPref (ScalarQuery)
SQL->>DB: INSERT (USER_PREFERENCE_SEQ.nextval)
end
end
PD-->>Caller: true
Design constraints¶
- Deviation from standard BOF data-access pattern: This library does not implement the standard
clsBusinessBase/clsBusinessCollectionBase+IBusinessCriteriaobject-lifecycle pattern used elsewhere in the framework. There is no nestedCriteriaclass and noCreateSQL/RetrieveSQL/InsertSQL/UpdateSQL/DeleteSQLproperties. Instead,PreferenceDataissues inline Oracle SQL directly viaSqlHelper.ResultSetQueryandSqlHelper.ScalarQuery<T>. This is a deliberate architectural deviation that should be noted by developers expecting the standard business-object model. - The library targets a single table (USER_PREFERENCE) with no joins or foreign-key relationships; all 7 cataloged SQL statements (see SQL catalog) reference only this table.
- The
SAIF.Frameworkdependency is resolved as a compiled binary reference (HintPath) rather than a<ProjectReference>, though the local.slnbuilds against the siblingSAIF.Framework.Coreproject's output.* - No configuration retrieval mechanism exists in this library (no
IEnvironmentService,ConfigurationManager.AppSettings,Web.config/App.config, orDbConnectionManagerusage) — the database/portal execution context is entirely supplied by the caller through the injectedIDataPortalInfo. - No authentication, authorization, or segregation-of-duties logic exists in this library;
userIdis used purely as a data key for scopingUSER_PREFERENCErows, not as an authorization decision point. - Open question — possible duplicate implementation: A separate
PreferenceData.vbimplementing similar preference persistence exists atSAIF.Framework.Core\Preferences\PreferenceData.vb. That file belongs toSAIF.Framework.Core, notSAIF.Framework.Preferences, and was out of scope for this analysis. Its relationship to this library'sPreferenceData(duplicate, legacy predecessor, or independent implementation) is unconfirmed.**
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
- Overview
- Dependencies
- Operations and processes
- Business rules
- Configuration
- Database tables
- SQL catalog
- API reference
Sources¶
- SAIF.Framework.Preferences\Preference.cs
- SAIF.Framework.Preferences\PreferenceData.cs
- SAIF.Framework.Preferences\SAIF.Framework.Preferences.csproj
- SAIF.Framework.Core\V1\DataAccessLayer\SqlHelper.vb
- SAIF.Framework.Core\Preferences\PreferenceData.vb