Skip to content

SAIF.Presentation.Web.Binding.Infragistics111 architecture

SAIF.Presentation.Web.Binding.Infragistics111 implements SAIF's declarative "object binder" — a two-way data binding and validation framework that connects SAIF BOF business objects to ASP.NET WebForms and Infragistics 11.1 controls, with automatic error-message aggregation and error-state control formatting. Unlike its sibling presentation libraries, it has no compile-time reference to the SAIF BOF framework; it detects business objects purely by walking the runtime base-class chain for the names clsBusinessBase / clsBusinessCollectionBase.

Responsibilities

  • Provide a page-level binding container (clsObjectBindManager) that registers, initializes, validates, and synchronizes ~24 control-specific binders against business-object properties.
  • Define the binder contract (clsObjectBinderBase) — Init, ObjectToControl, ControlToObject — shared reflection get/set helpers, padding support, and IDataErrorInfo-driven error harvesting.
  • Aggregate validation errors from bound business objects and application-supplied custom validators (clsCustomValidator) into a single formatted message surfaced to an error label or SAIFMessage control.
  • Supply strongly-typed binding-argument data contracts (clsObjectBindingArgs hierarchy, PadArgs) so applications can configure a binding without long positional Add calls.

Component boundaries

  • Manager layer (clsObjectBindManager, a System.Web.UI.Control): owns the binder collection, the validation-object dictionary, the aggregated error list, and the page-lifecycle hooks (OnLoad → initialize binders, OnPreRender → optional auto-bind). It is the library's only public entry point.
  • Binder abstraction layer (clsObjectBinderBase): the three-method binder contract plus shared reflection, padding, and error-formatting behavior common to every concrete binder.
  • Binder implementation layer — 24 concrete binders split across ASP.NET controls, Infragistics classic (WebUI) controls, and Infragistics current (Web.UI) controls, each knowing how to read/write its specific control property and which control event to subscribe to.
  • Argument/data-contract layer (clsObjectBindingArgs hierarchy, PadArgs): strongly-typed parameter objects for the Add overloads.
  • Validation layer (clsCustomValidator plus PropertyValidator/MethodValidator/ CustomValidator delegates): application-supplied validation participating in the same error pipeline as property-level errors.

Interaction model

  • A consuming page registers bindings during setup (Configure/Page_Load) via one of clsObjectBindManager's ~60 Add overloads; overload resolution on the control's compile-time type selects the matching concrete binder.
  • On OnLoad, each binder's Init wires up control change-event handlers (when UseEvents is True).
  • DataBind() (or PreRender-triggered auto-bind) pushes business-object property values into controls (ObjectToControl); BindToObject() pulls edited control values back onto business objects (ControlToObject), either on a control's change event or on demand.
  • Validate() reads each bind source's IsValid property (triggering BOF rule evaluation as a side effect†), then harvests per-property errors through IDataErrorInfo and runs any registered clsCustomValidator checks, aggregating distinct messages into FormattedErrorMessage.
  • The library never references SAIF.BOF.Framework at compile time: IsSAIFFrameWorkObject (duplicated in clsObjectBinderBase and clsObjectBindManager) walks the bound object's runtime base-class chain looking for the type names clsBusinessBase or clsBusinessCollectionBase; when matched, the binder reads that object's MyGuid property (a SAIF.Framework.Core member†) as the validation key.

Architecture diagram

The following diagram shows one full page cycle through the binder.

flowchart TD
    A["Page Configure/Load<br>binder.Add(control, object, property, bindType)"] --> B["clsObjectBindManager<br>m_Bindings + m_ValidationObjects"]
    B --> C["OnLoad: Binder.Init()<br>subscribe to control change events"]
    C --> D{"BindType"}
    D -->|ObjectToControl or TwoWay| E["DataBind()<br>Binder.ObjectToControl()"]
    E --> F["Control shows object value"]
    F --> G["User edits control"]
    G --> H{"UseEvents?"}
    H -->|Yes| I["Change event handler<br>ControlToObject()"]
    H -->|No| J["BindToObject()<br>ControlToObject()"]
    I --> K["Business object property updated"]
    J --> K
    K --> L["Validate()"]
    L --> M["ValidateBindSources()<br>read IsValid on each bind source"]
    L --> N["Binder.GetErrors()<br>IDataErrorInfo.Item(property)"]
    L --> O["clsCustomValidator.PerformValidation()"]
    N --> P["Aggregate distinct messages<br>SetControlFormat(False)"]
    O --> P
    P --> Q["ErrorLabel.Text / SAIFMessage.Text<br>= FormattedErrorMessage"]

Sequence diagram

The following diagram shows the primary validate/error-aggregation sequence.

sequenceDiagram
    participant Page
    participant Manager as clsObjectBindManager
    participant Binder as clsObjectBinderBase
    participant BizObj as Bound business object
    Page->>Manager: Validate()
    Manager->>BizObj: Read IsValid (per bind source)
    BizObj-->>Manager: rule evaluation side effect
    Manager->>Binder: GetErrors()
    Binder->>BizObj: IDataErrorInfo.Item(property)
    BizObj-->>Binder: Error message(s)
    Binder-->>Manager: Aggregated errors
    Manager->>Manager: SetControlFormat(False)
    Manager-->>Page: FormattedErrorMessage

Design constraints

  • No compile-time dependency on SAIF.BOF.Framework exists; business-object detection is purely behavioral (base-class name matching), so this library's correctness depends on the naming convention of clsBusinessBase / clsBusinessCollectionBase remaining stable in SAIF.Framework.Core†.
  • The library performs no data access, configuration, or security logic of its own; it is a pure in-memory presentation/binding layer between controls and whatever business object the caller supplies.
  • Error messages are concatenated into FormattedErrorMessage without HTML encoding — a potential XSS path if any bound business-rule message contains attacker-influenced text.*
  • Validate() and RefreshValidation() share ~50 lines of duplicated logic; the only difference is that RefreshValidation omits the bind-source IsValid read.
  • clsObjectBinderBase.SetObjectValueAsString computes a padded value but writes the object property from the unpadded value, so PadTarget.Object padding has no observable effect.

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. Statements marked with † were retrieved from a dependency library's own documentation via the Legends CLI RAG service.

Sources

  • SAIF.Presentation.Web.Binding.Infragistics111/clsObjectBindManager.vb
  • SAIF.Presentation.Web.Binding.Infragistics111/clsObjectBinderbase.vb
  • SAIF.Presentation.Web.Binding.Infragistics111/clsCustomValidator.vb
  • SAIF.Presentation.Web.Binding.Infragistics111/clsObjectBindingArgs.vb
  • SAIF.Presentation.Web.Binding.Infragistics111/Enums.vb
  • SAIF.Presentation.Web.Binding.Infragistics111/SAIF.Presentation.Web.Binding.Infragistics111.vbproj