---
title: SAIF.Framework.Bindable architecture
summary: Architectural responsibilities, boundaries, and interaction patterns.
status: draft
owner: <owner>
last_reviewed: 2026-07-23
library: SAIF.Framework.Bindable
reference_type: package
---

# SAIF.Framework.Bindable architecture

SAIF.Framework.Bindable is a base-class framework library that supplies three independent, unrelated abstract base classes — `clsBindableBase`, `clsBindableCollectionBase`, and `clsRulesManagerBase` — intended to be inherited by business object classes elsewhere in the SAIF BOF stack. The library provides pure in-memory object-model plumbing (event wiring and `IBindingList` implementation) with no data access, UI rendering, or service/network code, and has zero internal or external framework dependencies beyond the .NET Framework BCL.

## Responsibilities
- Provide `clsBindableBase`, an abstract base exposing a serialization-safe `IsModifiedChanged` event and a protected `m_CriteriaObject` field for subclasses that need to support data-binding change notification.
- Provide `clsBindableCollectionBase`, an abstract base implementing `System.ComponentModel.IBindingList` over `System.Collections.CollectionBase`, so subclass collections can be bound to WinForms/WebForms data-bound controls (grids, list controls) with add/edit/remove/sort/find support hooks.
- Provide `clsRulesManagerBase`, an abstract base exposing `RuleBroken`/`RuleNotBroken` events (via the `RuleEvent` delegate) implementing a business-rule-violation notification pattern.
- Define no business operations, workflows, or concrete rule logic of its own — it defines only the reusable notification mechanisms consumed by subclasses outside this library's scope.

## Component boundaries
- `clsBindableBase`: boundary is single-object change notification. Exposes `IsModifiedChanged` and `OnIsModifiedChanged()`; does not implement any binding-list contract itself.
- `clsBindableCollectionBase`: boundary is collection-level data binding. Implements `IBindingList` explicitly and overrides `CollectionBase` insert/remove/set/clear hooks to raise `ListChanged`; provides protected virtual extension points (`OnAddNew()`, `IBindingList_Find(...)`, sort/search hooks) for subclass override.
- `clsRulesManagerBase`: boundary is rule-violation notification only. Exposes `RuleBroken`/`RuleNotBroken` events and `OnRuleBroken`/`OnRuleNotBroken` methods; contains no rule evaluation or validation logic itself.
- `clsBindableBase` and `clsRulesManagerBase` are not related to each other by inheritance or composition; they are independent base classes co-located in the same assembly/namespace, presumably because both support the "bindable business object" convention used elsewhere in the framework.*
- The protected `m_CriteriaObject` field appears in both `clsBindableBase` and `clsBindableCollectionBase` with identical name/type/visibility, suggesting a convention where a subclass's SAIF BOF `Criteria` object is expected to be assigned to this field by descendants, though no usage of the field appears within this library itself.*

## Interaction model
- All three base classes are consumed exclusively through inheritance by subclasses defined outside this library; no consumers of any of the three classes exist within this library's own source.**
- Interaction is entirely synchronous, in-process event dispatch: a subclass instance calls a protected `On*` method, which raises the corresponding public event to any subscriber (typically a data-bound UI control or business-logic consumer).
- `clsBindableCollectionBase`'s `On*Complete` overrides (`OnInsertComplete`, `OnClearComplete`, `OnRemoveComplete`, `OnSetComplete`) are invoked automatically by the underlying `CollectionBase` machinery in response to collection mutations, and in turn raise `OnListChanged`.
- No I/O, network, or database interaction occurs anywhere in this library; all flows are in-memory object-model plumbing.

The following diagram shows the high-level component structure and how subclasses outside this library interact with the base classes.

```mermaid
flowchart TD
	Sub1["Subclass business object<br>(outside this library)"] -->|inherits| A[clsBindableBase]
	Sub2["Subclass business collection<br>(outside this library)"] -->|inherits| B[clsBindableCollectionBase]
	Sub3["Subclass rules manager<br>(outside this library)"] -->|inherits| C[clsRulesManagerBase]
	A -->|raises| E1[IsModifiedChanged event]
	B -->|raises| E2[ListChanged event]
	C -->|raises| E3["RuleBroken / RuleNotBroken events"]
	E1 --> UI["Data-bound UI / consumer"]
	E2 --> UI
	E3 --> UI
```

## Sequence diagram
The following diagram shows the primary in-process notification sequence common to all three base classes (using rule-violation notification as the representative example).

```mermaid
sequenceDiagram
	participant Subclass
	participant RulesManagerBase as clsRulesManagerBase
	participant Subscriber
	Subclass->>RulesManagerBase: OnRuleBroken(rule)
	RulesManagerBase->>Subscriber: RuleBroken(rule) event invocation
	Subscriber-->>RulesManagerBase: (handler executes)
```

## Design constraints
- Zero internal project references and zero external NuGet packages; the only dependencies are the .NET Framework BCL assemblies `System`, `System.Data`, and `System.Xml`, targeting .NET Framework 4.6.2.
- **Unguarded event invocation defect**: `clsRulesManagerBase.OnRuleBroken` and `OnRuleNotBroken` invoke their respective event delegates (`RuleBroken(rule)`, `RuleNotBroken(rule)`) directly with no null check. If a subclass calls either method while no listener has subscribed, a `NullReferenceException` is thrown at runtime.* This contrasts with `clsBindableBase.OnIsModifiedChanged()`, which guards its invocation with `if (IsModifiedChanged != null)`. Consumers must ensure a subscriber is always attached before triggering rule notifications, or the base class must be corrected to add the equivalent guard. See also [BR-001](business-rules.md#br-001-rule-violation-notification-requires-a-subscribed-listener).
- The three base classes are unrelated to one another (no shared inheritance or composition), so consumers must independently opt into each capability (bindable state, bindable collection, rule notification) by inheriting from the relevant base class.
- The intended relationship between `m_CriteriaObject` and the `IBusinessCriteria`/`Criteria` pattern used elsewhere in the SAIF BOF stack is inferred but not confirmed by any code in this library.*
- Actual subclassing usage (which business objects derive from these base classes) is outside this library's scope and unverified.**

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Configuration](configuration.md)
- [API reference](api/index.md)

> **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.Bindable\clsBindableBase.cs`
- `SAIF.Framework.Bindable\clsBindableCollectionBase.cs`
- `SAIF.Framework.Bindable\clsrulesmanagerbase.cs`
- `SAIF.Framework.Bindable\SAIF.BOF.Framework.Bindable.csproj`
- `SAIF.Framework.Bindable\SAIF.Framework.Bindable.sln`
