Skip to content

SAIF.Framework.Core architecture

SAIF.Framework.Core is the foundational Business Object Framework (BOF) layer of the repository (frameworkDensity: 0 — it is the framework's core; other repository libraries depend on it, not vice versa). It defines the abstract contracts and base implementations that all domain-specific business-object libraries inherit from (clsBusinessBase, clsBusinessCollectionBase(Of ItemType), IBusinessCriteria), the data-access plumbing (IDataPortalInfo, IDataAccess, Oracle/SQL Server data layers), and cross-cutting concerns (business rules engine, smart values, property tracking, XML/report building). Two generations of several subsystems — the business rules engine and smart value types — coexist side by side in the same assembly under V1\ and V2\ folders/namespaces.

Responsibilities

  • Provide the abstract business-object base classes (clsBusinessBase, clsBusinessCollectionBase) that all domain business objects in the repository inherit from, including n-level undo (BeginEdit/CancelEdit/ApplyEdit), object linking (ILinkItem), and collection traversal (ITraversion).
  • Provide a parallel REST/API-oriented business-object model (clsBusinessApiBase, clsBusinessCollectionApiBase, clsBusinessApiCriteriaBase) built on RestSharp, for business objects backed by web APIs rather than direct SQL.
  • Abstract database access behind IDataPortalInfo/IDataAccess so business objects are decoupled from the concrete Oracle or SQL Server driver in use (IDataLayer, implemented by clsMSOracleDataLayer and clsSQLDataLayer).
  • Host the business rules engine (clsRulesManager in V1, RuleManager in V2) that stores and invokes rule-handler delegates and tracks broken-rule results.
  • Supply DB-null-safe "smart value" property wrapper types (clsSmartString/clsSmartDate/clsSmartDecimal in V1; SmartString/SmartDate/SmartDecimal/SmartInteger in V2) used throughout BOF business objects.
  • Supply supporting cross-cutting infrastructure: property-change tracking (TrackedProperty/TrackedProperties, TrackedApiProperty/TrackedApiProperties), code-table/lookup abstractions (clsCodeTableBase, clsCodeCollection), validation helpers (clsValidation, clsCharacterAnalyzer), XML/report building (clsReportSpecification, clsReportXMLBuilder, SAIFXDocument), and environment/preference utilities (clsProperties, SAIFEnvironment, Preference/PreferenceData).

Component boundaries

  • Classic business-object hierarchy (V1\BaseItems): clsBusinessBase (MustInherit; inherits clsUndoableBase; implements IEditableObject, ICloneable, IDataErrorInfo, ISerializationNotification, ILinkItem) and clsBusinessCollectionBase/clsBusinessCollectionBase(Of ItemType) (inherits clsSortableCollectionBase; implements ICloneable, ISerializationNotification, ITraversion, IDataErrorInfo). Each clsBusinessBase instance owns a clsRulesManager (m_Rules) exposed via the Rules property. Criteria support is provided by clsBusinessCriteriaBase (all five SQL properties overridable) and clsRetrieveOnlyBusinessCriteria (throws ApplicationException for Create/Insert/Update/Delete SQL, leaving only Retrieve).
  • API-based business-object hierarchy (V1\Api): clsBusinessApiBase (inherits clsUndoableApiBase) and clsBusinessCollectionApiBase mirror the classic hierarchy's shape but are backed by REST calls instead of SQL. clsBusinessApiCriteriaBase implements IBusinessApiCriteria (which extends IBusinessCriteria) with all five SQL properties overridable but empty by design — API-backed criteria carry ApiRoutes (SAIFDictionary(Of IApiRoute)) and a GetApiClient/FormatRoute mechanism instead of SQL text. REST plumbing (ApiClient/IApiClient, ApiRequest/IApiRequest, ApiResult/IApiResult, clsDataApiAccess/IDataApiAccess) is built on the RestSharp package and reached via IDataPortalInfo.ApiClients/DataApiAccessLayer.
  • Data access layer (V1\DataAccessLayer): IDataAccess/clsDataAccess is the central data-access registry managing multiple IDataPortal instances keyed by PortalID. IDataPortalInfo/clsDataPortalInfo is the central "DPI" object passed to every business object, exposing ProcessPortalRequest, ExecuteScalar, GetResultSet, GetNextSeqNum, GetXML, NewPortalRequest, ApiClients, and DataApiAccessLayer. IDataLayer is the abstraction implemented by both clsMSOracleDataLayer (Oracle, via Oracle.ManagedDataAccess, sets DBMSType = clsDataAccess.clsEnvironment.DBMS.Oracle) and clsSQLDataLayer (SQL Server), each with parallel driver-specific IDataPortal/IDataRequest/IPortalRequest implementations (clsMSOracleDataPortal/MSOracleDataRequest/MSOraclePortalRequest vs. SQLDataPortal/SQLDataRequest/SQLPortalRequest). The DataPortalType enum (MSOracle, Oracle, SQLServer, ActiveDirectory, Api, ApiAndDb) confirms multi-source targeting, including the API/DB hybrid, is a first-class design goal.*
  • Business rules engine (V1\BusinessRules and V2\BusinessRules): V1's clsRulesManager stores and invokes rule-handler delegates and tracks results (clsRule, clsRuleArgs, clsRuleAttributes, clsRuleCollection, clsRuleInformation, clsBrokenRule/clsBrokenRuleCollection, clsBrokenRuleResult/clsBrokenRuleResultManager/clsBrokenRuleResultReason). V2 provides a modernized, non-Hungarian-prefixed rework of the same concepts (RuleManager, BusinessRule, BrokenRule, BrokenRuleCollection, BusinessRuleCollection, BusinessRuleInformation, RuleArgs) coexisting in the same assembly.
  • Smart value types (V1\SmartValues and V2\SmartValues): V1 supplies clsSmartString, clsSmartDecimal, clsSmartDate, clsSmartProperty as DB-null-safe property wrappers. V2 supplies a modernized parallel set (SmartValue, SmartString, SmartDate, SmartDecimal, SmartInteger, ISmartValue).
  • Supporting infrastructure: clsUndoableBase/clsSortableCollectionBase provide the undo and sortable-collection mechanics beneath the business-object layer; TrackedProperty/TrackedProperties/ITrackedProperty (and API counterparts TrackedApiProperty/TrackedApiProperties) provide property-change tracking; clsCodeTableBase/clsCodeCollection/clsCodeItem/clsCodeDescription provide code-table/lookup abstractions; clsReportSpecification/clsReportXMLBuilder/SAIFXDocument/SAIFXElement/ReportableAttribute (V1) and clsErrorCodes/CustomXmlSerializer (V2) provide XML/report-building utilities.

Interaction model

  • Every clsBusinessBase-derived business object owns a clsRulesManager (Rules property) used to enforce business rules via Rules.CheckRules("RuleName"), typically invoked from a property setter.*
  • Business objects reach the database exclusively through the DPI (IDataPortalInfo/clsDataPortalInfo), which delegates to IDataAccess.ProcessPortalRequest; this decouples business-object code from the concrete Oracle or SQL Server driver in use.
  • For API-backed business objects, clsBusinessApiCriteriaBase.GetApiClient/FormatRoute resolves a named IApiClient from the DPI (IDataPortalInfo.ApiClients) and formats a configured IApiRoute template with call-site arguments, in place of executing SQL.
  • clsUndoableBase (base of clsBusinessBase) and clsSortableCollectionBase (base of clsBusinessCollectionBase) provide n-level undo (BeginEdit/CancelEdit/ApplyEdit) beneath the business-object layer, supporting UI edit/cancel scenarios.
  • Broken-rule state raised by the rules engine surfaces to UI consumers via IDataErrorInfo.Error/Item, implemented on both clsBusinessBase and clsBusinessCollectionBase.
  • clsRetrieveOnlyBusinessCriteria enforces, at the framework level, that mutating operations (Create/Insert/Update/Delete) are unsupported for read-only business objects, by throwing ApplicationException("SQL property not available.") if those properties are accessed.
  • ISerializationNotification (Deserialized/Serialized/Serializing), implemented on both clsBusinessBase and clsBusinessCollectionBase, provides hooks for custom logic around binary/remoting serialization.

Architecture diagram

The following diagram shows the dual business-object hierarchies converging on the shared data-portal abstraction, and the V1/V2 rules engine coexistence.

flowchart TD
    BB[clsBusinessBase<br>+ clsBusinessCollectionBase] --> RM1[clsRulesManager V1]
    AB[clsBusinessApiBase<br>+ clsBusinessCollectionApiBase] --> CB[clsBusinessApiCriteriaBase]
    BB --> CRIT[clsBusinessCriteriaBase /<br>clsRetrieveOnlyBusinessCriteria]
    CRIT --> DPI[IDataPortalInfo / clsDataPortalInfo]
    CB --> DPI
    DPI --> DAL[IDataAccess / clsDataAccess]
    DAL --> ORA[clsMSOracleDataLayer<br>Oracle.ManagedDataAccess]
    DAL --> SQL[clsSQLDataLayer<br>SQL Server]
    DPI --> APICLIENT[ApiClient / IDataApiAccess<br>RestSharp]
    RM2[RuleManager V2] -.not wired into base classes.-> BB

Sequence diagram

The following diagram shows the primary business-object save sequence, from rule enforcement through the data portal to the concrete database driver.

sequenceDiagram
    participant Consumer as Business object (clsBusinessBase subclass)
    participant Rules as clsRulesManager
    participant DPI as IDataPortalInfo
    participant DAL as IDataAccess
    participant Driver as IDataLayer (Oracle/SQL Server)
    Consumer->>Rules: CheckRules("RuleName")
    Rules-->>Consumer: Broken rules (if any)
    Consumer->>DPI: ProcessPortalRequest(criteria)
    DPI->>DAL: ProcessPortalRequest
    DAL->>Driver: Execute via IDataPortal/IDataRequest
    Driver-->>DAL: Result set / scalar / XML
    DAL-->>DPI: Result
    DPI-->>Consumer: Result

Design constraints

  • Core has outbound dependencies on sibling framework libraries (SAIF.Framework.Security, SAIF.Framework.Connection, SAIF.Framework.Logging, SAIF.Framework.DNS, SAIF.Framework.Security.EnvironmentApi, SAIF.Framework.Bindable) via project references and VB Imports — despite being the architectural base, Core is not a dependency-free leaf.*
  • Two generations of the business rules engine (clsRulesManager/V1 and RuleManager/V2) and of smart value types (clsSmartString/etc. V1 and SmartString/etc. V2) coexist in the same assembly; no code within Core itself was observed wiring V2 rule or smart-value types into clsBusinessBase, so V1 remains the active base-class integration point (clsBusinessBase.m_Rules As New clsRulesManager).**
  • The data-access abstraction (IDataLayer) is designed to support Oracle and SQL Server interchangeably, plus Active Directory and REST API sources, via the DataPortalType enum (MSOracle, Oracle, SQLServer, ActiveDirectory, Api, ApiAndDb); Core provides only the driver/portal plumbing, never domain-specific SQL statements (0 non-empty SQL properties across all IBusinessCriteria implementations in Core).
  • clsBusinessApiCriteriaBase's SQL properties are always empty by design — API-backed business objects must not use the SQL path; the Api/ApiAndDb DataPortalType values confirm this hybrid model is intentional rather than a stopgap.*
  • Core defines no authentication/authorization enforcement logic of its own; SAIF.Framework.Security is imported as a namespace but no call site within Core was found invoking a security API from it during analysis.**
  • Core does not itself consume IEnvironmentService or ConfigurationManager.AppSettings; its only configuration surface is the legacy VB "My Namespace" ApplicationSettingsBase pattern (one setting, the SAIFDates web-service URL) and the Oracle ODP.NET oracle.manageddataaccess.client config section.
  • SAIF.Framework.Core is the primary/root project for the repository's single NuGet package pipeline (SAIF.BOF.Framework), and the packaged nuspec bundles compiled DLLs from referenced projects plus raw .vb/.cs source from every top-level library folder in the repository.

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.

Sources

  • SAIF.Framework.Core\V1\BaseItems\clsBusinessBase.vb
  • SAIF.Framework.Core\V1\BaseItems\clsBusinessCollectionBase.vb
  • SAIF.Framework.Core\V1\BaseItems\clsUndoableBase.vb
  • SAIF.Framework.Core\V1\BaseItems\clsSortableCollectionBase.vb
  • SAIF.Framework.Core\V1\BaseItems\clsBusinessCriteriaBase.vb
  • SAIF.Framework.Core\V1\BaseItems\clsRetrieveOnlyBusinessCriteria.vb
  • SAIF.Framework.Core\V1\Api\clsBusinessApiBase.vb
  • SAIF.Framework.Core\V1\Api\clsBusinessCollectionApiBase.vb
  • SAIF.Framework.Core\V1\Api\clsBusinessApiCriteriaBase.vb
  • SAIF.Framework.Core\V1\Interfaces\iDataAccess.vb
  • SAIF.Framework.Core\V1\DataAccessLayer\clsDataAccess.vb
  • SAIF.Framework.Core\V1\Interfaces\iDataPortalInfo.vb
  • SAIF.Framework.Core\V1\DataAccessLayer\clsDataPortalInfo.vb
  • SAIF.Framework.Core\V1\Interfaces\iDataPortal.vb
  • SAIF.Framework.Core\V1\Interfaces\iDataRequest.vb
  • SAIF.Framework.Core\V1\Interfaces\iPortalRequest.vb
  • SAIF.Framework.Core\V1\Interfaces\IDataLayer.vb
  • SAIF.Framework.Core\V1\DataAccessLayer\MSOracle\MSOracleDataLayer.vb
  • SAIF.Framework.Core\V1\DataAccessLayer\SQLServer\SQLDataLayer.vb
  • SAIF.Framework.Core\V1\DataAccessLayer\DataAccessEnums.vb
  • SAIF.Framework.Core\V1\BusinessRules\clsRulesManager.vb
  • SAIF.Framework.Core\V2\BusinessRules\ (RuleManager and related types)
  • SAIF.Framework.Core\V1\SmartValues\ (clsSmartString, clsSmartDecimal, clsSmartDate, clsSmartProperty)
  • SAIF.Framework.Core\V2\SmartValues\ (SmartValue, SmartString, SmartDate, SmartDecimal, SmartInteger, ISmartValue)
  • SAIF.Framework.Core\SAIF.BOF.Framework.Core.vbproj
  • SAIF.Framework.Core\SAIF.BOF.Framework.Core.nuspec
  • SAIF.Framework.Core\app.config
  • Pipelines\build-vars.yml