Application context initialization¶
AppManagerBase is an abstract application-manager base class inherited by concrete application managers throughout the BOF stack. Before a manager can service a request it must run its one-time initialization sequence, which wires up its data-access layer and hands control to subclass-supplied hooks for the rest of setup. This operation captures that sequence and the related context-validity check that callers use afterward.
| Field | Value |
|---|---|
| Operation ID | OP-APP-01 |
| Trigger | A consuming subclass calls the protected Initialize() method, typically from its own constructor or an explicit setup call |
| Inputs | The clsSecurityPrincipal supplied to the protected constructor; subclass-specific state read by OnInitialize() and OnCreateDataLayer() |
| Outputs | A manager instance with its lazily-created ApplicationDataAccess data layer available through the DataLayer property; subclass-specific initialization side effects |
| Primary components | AppManagerBase.New, AppManagerBase.Initialize, AppManagerBase.OnInitialize (MustOverride), AppManagerBase.OnCreateDataLayer (MustOverride), AppManagerBase.DataLayer, AppManagerBase.ValidContext |
| Entry point | Application\SAIF.Application\AppManagerBase.vb |
Steps¶
- Construct the manager. The protected constructor
New(inSecurityPrincipal As clsSecurityPrincipal)stores the caller-supplied security principal inm_SecurityPrincipal, exposed to subclasses through the read-onlySecurityPrincipalproperty. No data layer is created at construction time. - Call
Initialize(). The subclass (or its own constructor) invokes the protectedInitialize()method, which runs exactly two steps in order and returns nothing: OnInitialize()— aMustOverridehook the subclass implements to perform its own setup (for example, reading request context or seeding default state).OnCreateDataLayer()— aMustOverridehook the subclass implements to populate the manager'sApplicationDataAccessinstance with the portal entries it will need.- Because both hooks are abstract,
AppManagerBaseitself performs no concrete initialization work beyond invoking them in this fixed order; all actual behavior depends on the subclass implementation.* - Lazily materialize the data layer. The first time any code reads the
DataLayerproperty,AppManagerBasechecks whetherm_DataLayerisNothingand, if so, constructs a newApplicationDataAccess(SecurityPrincipal.UserName.ToString)— passing the security principal's user name as the batch-user constructor argument — and caches it for the life of the manager instance. - On failure: if
SecurityPrincipalisNothing(constructor never called with a valid principal, orOnInitialize()/OnCreateDataLayer()readDataLayerbefore construction completes), theUserName.ToStringcall raises aNullReferenceException. This is not explicitly guarded.* - Register portals during
OnCreateDataLayer(). Subclasses typically callDataLayer.CreateSQLServerPortal(key)orDataLayer.CreateOraclePortal(key)from within theirOnCreateDataLayer()override; see Multi-database portal registration for that operation's own step sequence, which this step delegates to. - This is an embedded delegation to a sibling operation of this same library, not an external dependency — no
> Origincallout is required because both operations are documented in this library's ownoperations/folder. - Confirm context validity before use. Once initialized, callers read the
ValidContextproperty to decide whether the manager instance has enough state to proceed with a retrieve or write: ValidContextdelegates directly toOnValidContext(), anotherMustOverridehook.- The subclass implementation inspects whatever state it considers necessary (for example, whether a required identifier or context key has been set) and returns
TrueorFalse. - If
ValidContextreturnsFalse: callers are expected to avoid invokingRetrieve()orWrite();AppManagerBasedoes not itself block those calls when the context is invalid — enforcement is left to the subclass or caller.* - Track explicit context-set state separately.
AppManagerBasealso maintains a privatem_ContextSetflag, toggled by the protectedMarkContextSet()andMarkContextNotSet()methods, exposed read-only asContextSet. This is a distinct signal fromValidContext—ContextSetrecords whether the subclass has explicitly marked the context as entered, whileValidContextis a subclass-computed judgment of whether that context is usable.*
Process flow¶
The following diagram visualizes the initialization and context-validity sequence.
flowchart TD
Start([Subclass constructor runs]) --> Ctor[AppManagerBase.New stores<br>SecurityPrincipal]
Ctor --> Init[Subclass calls Initialize]
Init --> OnInit[OnInitialize hook<br>subclass-defined]
OnInit --> OnLayer[OnCreateDataLayer hook<br>subclass-defined]
OnLayer --> Portal[Register SQL Server / Oracle<br>portals via DataLayer]
Portal --> MarkSet[Subclass calls MarkContextSet<br>when context is entered]
MarkSet --> Valid{Caller reads ValidContext}
Valid --> OnValid[OnValidContext hook<br>subclass-defined]
OnValid -->|True| Proceed([Manager ready for<br>Retrieve or Write])
OnValid -->|False| Block([Caller should not proceed;<br>not enforced by AppManagerBase])
Failure and edge-case behavior¶
Initialize()callsOnInitialize()unconditionally beforeOnCreateDataLayer(); a subclass that needs data-layer state duringOnInitialize()cannot get it from this base sequence.*- The lazy
DataLayergetter has no null-check onSecurityPrincipal, so a manager constructed without a valid principal (or a subclass path that readsDataLayerbefore the constructor sets it) fails with aNullReferenceExceptionrather than a descriptive error.* ValidContextandContextSetare independent flags; nothing inAppManagerBasekeeps them synchronized, so a subclass could mark the context set (MarkContextSet()) whileOnValidContext()still reports invalid context, or vice versa.*- Because
OnInitialize(),OnCreateDataLayer(), andOnValidContext()are allMustOverride, the base class provides no default behavior at all — every concrete initialization or validity rule lives in the consuming application's subclass and is outside this library's documentation scope.
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¶
Application\SAIF.Application\AppManagerBase.vbApplication\SAIF.Application\ApplicationDataAccess.vb