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
Preferencegroups 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, andPrefScope.WebLevel, exposed through theItemindexer and theAdd/Remove/Clear/Deletemembers. - Resolve the "current page" identity using a dual strategy: parsing
System.Web.HttpContext.Current.Request.Pathin web contexts, or falling back to an explicitOverridePagevalue orSystem.Diagnostics.StackTracereflection in non-web contexts*. - Persist in-memory preference changes back to the Oracle-backed
PreferenceDatastore on explicitSave()calls, serializing each preference group's items to JSON viaJavaScriptSerializer. - Resolve the Oracle connection target for its own persistence needs through the
SAIF.Framework.Commonenvironment-service abstraction (AppGlobal.EnvironmentService.GetConfigSetting(EnvironmentConfigKeys.OracleDatabase)), rather than reading configuration locally (see Configuration).
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 noIBusinessCriteriapattern itself; all durable storage is delegated to the externalPreferenceDatatype.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 everyItem/Add/Remove/Clearcall.- 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 byLoad(). - Cross-cutting boundary —
clsLogTrace(fromSAIF.BOF.Framework): method-entry/exit tracing wrapped aroundRemove()andSave().
Interaction model¶
- Consumers (web pages, Windows Forms, or other SAIF.Presentation.* libraries) construct a
clsPreferencesinstance, 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'sinUserIDparameter*. - Reads use the
Itemindexer (three overloads) to fetch a value scoped by application/page/key entirely from the in-memory_Preferenceslist — 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 callsSave(). Save()persists only the preference groups whoseApplicationNamematches the currentm_Application, viaPreferenceData.SavePreferences; itsBooleanreturn value is not a reliable success indicator because of a dead-code path that always returnsFalse*.- This library is consumed as a same-repo
<ProjectReference>(its.vbsource, 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 aPreferencesproperty backed byclsPreferences),SAIF.Presentation.Web.Controls.V2.Menu(SAIFMenu, usingPrefScope.AppLevelto persist aSHOWAPPSmenu preference), andSAIF.Presentation.Web.Controls.AJAX.Infragistics103(InfragisticsGridCustomizer, resolving aclsPreferencesinstance viaBindingUtility.GetObject).
Architecture diagram¶
The following diagram shows how consumer libraries obtain and use the clsPreferences service, and how it delegates persistence downstream.
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.
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 viaAppGlobal.EnvironmentService.GetConfigSetting; the library defines noApp.config/Web.configand reads noAppSettingsdirectly. Save()'s boolean return value cannot be trusted to detect failure (dead code afterReturn result); only a thrownApplicationExceptionsignals a save error*.- The 3-argument constructor's XML documentation describes file-based storage via a
preferencesRootDirectoryparameter, but the parameter is accepted and ignored — the live implementation always loads from the Oracle-backedPreferenceData, so the documented and actual behavior diverge*. - This project's compiled binary is not what ships in the
SAIF.BOF.Presentation.Web.Infragistics103NuGet package; only its.vbsource is bundled (per the root.nuspec) for consumers to recompile alongsideSAIF.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¶
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