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 onRestSharp, for business objects backed by web APIs rather than direct SQL. - Abstract database access behind
IDataPortalInfo/IDataAccessso business objects are decoupled from the concrete Oracle or SQL Server driver in use (IDataLayer, implemented byclsMSOracleDataLayerandclsSQLDataLayer). - Host the business rules engine (
clsRulesManagerin V1,RuleManagerin V2) that stores and invokes rule-handler delegates and tracks broken-rule results. - Supply DB-null-safe "smart value" property wrapper types (
clsSmartString/clsSmartDate/clsSmartDecimalin V1;SmartString/SmartDate/SmartDecimal/SmartIntegerin 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; inheritsclsUndoableBase; implementsIEditableObject,ICloneable,IDataErrorInfo,ISerializationNotification,ILinkItem) andclsBusinessCollectionBase/clsBusinessCollectionBase(Of ItemType)(inheritsclsSortableCollectionBase; implementsICloneable,ISerializationNotification,ITraversion,IDataErrorInfo). EachclsBusinessBaseinstance owns aclsRulesManager(m_Rules) exposed via theRulesproperty. Criteria support is provided byclsBusinessCriteriaBase(all five SQL properties overridable) andclsRetrieveOnlyBusinessCriteria(throwsApplicationExceptionfor Create/Insert/Update/Delete SQL, leaving only Retrieve). - API-based business-object hierarchy (V1\Api):
clsBusinessApiBase(inheritsclsUndoableApiBase) andclsBusinessCollectionApiBasemirror the classic hierarchy's shape but are backed by REST calls instead of SQL.clsBusinessApiCriteriaBaseimplementsIBusinessApiCriteria(which extendsIBusinessCriteria) with all five SQL properties overridable but empty by design — API-backed criteria carryApiRoutes(SAIFDictionary(Of IApiRoute)) and aGetApiClient/FormatRoutemechanism instead of SQL text. REST plumbing (ApiClient/IApiClient,ApiRequest/IApiRequest,ApiResult/IApiResult,clsDataApiAccess/IDataApiAccess) is built on theRestSharppackage and reached viaIDataPortalInfo.ApiClients/DataApiAccessLayer. - Data access layer (V1\DataAccessLayer):
IDataAccess/clsDataAccessis the central data-access registry managing multipleIDataPortalinstances keyed byPortalID.IDataPortalInfo/clsDataPortalInfois the central "DPI" object passed to every business object, exposingProcessPortalRequest,ExecuteScalar,GetResultSet,GetNextSeqNum,GetXML,NewPortalRequest,ApiClients, andDataApiAccessLayer.IDataLayeris the abstraction implemented by bothclsMSOracleDataLayer(Oracle, viaOracle.ManagedDataAccess, setsDBMSType = clsDataAccess.clsEnvironment.DBMS.Oracle) andclsSQLDataLayer(SQL Server), each with parallel driver-specificIDataPortal/IDataRequest/IPortalRequestimplementations (clsMSOracleDataPortal/MSOracleDataRequest/MSOraclePortalRequestvs.SQLDataPortal/SQLDataRequest/SQLPortalRequest). TheDataPortalTypeenum (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
clsRulesManagerstores 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,clsSmartPropertyas DB-null-safe property wrappers. V2 supplies a modernized parallel set (SmartValue,SmartString,SmartDate,SmartDecimal,SmartInteger,ISmartValue). - Supporting infrastructure:
clsUndoableBase/clsSortableCollectionBaseprovide the undo and sortable-collection mechanics beneath the business-object layer;TrackedProperty/TrackedProperties/ITrackedProperty(and API counterpartsTrackedApiProperty/TrackedApiProperties) provide property-change tracking;clsCodeTableBase/clsCodeCollection/clsCodeItem/clsCodeDescriptionprovide code-table/lookup abstractions;clsReportSpecification/clsReportXMLBuilder/SAIFXDocument/SAIFXElement/ReportableAttribute(V1) andclsErrorCodes/CustomXmlSerializer(V2) provide XML/report-building utilities.
Interaction model¶
- Every
clsBusinessBase-derived business object owns aclsRulesManager(Rulesproperty) used to enforce business rules viaRules.CheckRules("RuleName"), typically invoked from a property setter.* - Business objects reach the database exclusively through the DPI (
IDataPortalInfo/clsDataPortalInfo), which delegates toIDataAccess.ProcessPortalRequest; this decouples business-object code from the concrete Oracle or SQL Server driver in use. - For API-backed business objects,
clsBusinessApiCriteriaBase.GetApiClient/FormatRouteresolves a namedIApiClientfrom the DPI (IDataPortalInfo.ApiClients) and formats a configuredIApiRoutetemplate with call-site arguments, in place of executing SQL. clsUndoableBase(base ofclsBusinessBase) andclsSortableCollectionBase(base ofclsBusinessCollectionBase) 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 bothclsBusinessBaseandclsBusinessCollectionBase. clsRetrieveOnlyBusinessCriteriaenforces, at the framework level, that mutating operations (Create/Insert/Update/Delete) are unsupported for read-only business objects, by throwingApplicationException("SQL property not available.")if those properties are accessed.ISerializationNotification(Deserialized/Serialized/Serializing), implemented on bothclsBusinessBaseandclsBusinessCollectionBase, 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 VBImports— despite being the architectural base, Core is not a dependency-free leaf.* - Two generations of the business rules engine (
clsRulesManager/V1 andRuleManager/V2) and of smart value types (clsSmartString/etc. V1 andSmartString/etc. V2) coexist in the same assembly; no code within Core itself was observed wiring V2 rule or smart-value types intoclsBusinessBase, 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 theDataPortalTypeenum (MSOracle,Oracle,SQLServer,ActiveDirectory,Api,ApiAndDb); Core provides only the driver/portal plumbing, never domain-specific SQL statements (0 non-empty SQL properties across allIBusinessCriteriaimplementations in Core). clsBusinessApiCriteriaBase's SQL properties are always empty by design — API-backed business objects must not use the SQL path; theApi/ApiAndDbDataPortalTypevalues confirm this hybrid model is intentional rather than a stopgap.*- Core defines no authentication/authorization enforcement logic of its own;
SAIF.Framework.Securityis 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
IEnvironmentServiceorConfigurationManager.AppSettings; its only configuration surface is the legacy VB "My Namespace"ApplicationSettingsBasepattern (one setting, theSAIFDatesweb-service URL) and the Oracle ODP.NEToracle.manageddataaccess.clientconfig section. SAIF.Framework.Coreis 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/.cssource 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.
Related documentation¶
Sources¶
SAIF.Framework.Core\V1\BaseItems\clsBusinessBase.vbSAIF.Framework.Core\V1\BaseItems\clsBusinessCollectionBase.vbSAIF.Framework.Core\V1\BaseItems\clsUndoableBase.vbSAIF.Framework.Core\V1\BaseItems\clsSortableCollectionBase.vbSAIF.Framework.Core\V1\BaseItems\clsBusinessCriteriaBase.vbSAIF.Framework.Core\V1\BaseItems\clsRetrieveOnlyBusinessCriteria.vbSAIF.Framework.Core\V1\Api\clsBusinessApiBase.vbSAIF.Framework.Core\V1\Api\clsBusinessCollectionApiBase.vbSAIF.Framework.Core\V1\Api\clsBusinessApiCriteriaBase.vbSAIF.Framework.Core\V1\Interfaces\iDataAccess.vbSAIF.Framework.Core\V1\DataAccessLayer\clsDataAccess.vbSAIF.Framework.Core\V1\Interfaces\iDataPortalInfo.vbSAIF.Framework.Core\V1\DataAccessLayer\clsDataPortalInfo.vbSAIF.Framework.Core\V1\Interfaces\iDataPortal.vbSAIF.Framework.Core\V1\Interfaces\iDataRequest.vbSAIF.Framework.Core\V1\Interfaces\iPortalRequest.vbSAIF.Framework.Core\V1\Interfaces\IDataLayer.vbSAIF.Framework.Core\V1\DataAccessLayer\MSOracle\MSOracleDataLayer.vbSAIF.Framework.Core\V1\DataAccessLayer\SQLServer\SQLDataLayer.vbSAIF.Framework.Core\V1\DataAccessLayer\DataAccessEnums.vbSAIF.Framework.Core\V1\BusinessRules\clsRulesManager.vbSAIF.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.vbprojSAIF.Framework.Core\SAIF.BOF.Framework.Core.nuspecSAIF.Framework.Core\app.configPipelines\build-vars.yml