SAIF.Services.ClaimInfoApi.Core architecture¶
SAIF.Services.ClaimInfoApi.Core is a small, leaf class library that implements a metadata-driven notification rule engine: it holds no state, performs no I/O, and has no internal or external dependencies beyond the .NET base class library, evaluating caller-supplied rule definitions against an arbitrary model at run time by compiling LINQ expression trees on demand.
Responsibilities¶
- Evaluate a set of
NotificationRuledefinitions in aNotificationMatrixagainst an arbitrary modelTand return the non-null results asNotificationResultobjects, keyed by rule position (NotificationRuleEngine.CalculateNotifications<T>, OP-CIA-01). - Resolve each rule's evaluation type (
int,bool, or string-like) from itsTypeNamemetadata and dispatch to the matching evaluation branch (OP-CIA-02). - Compile a rule's member name, operator name, and target value into a LINQ expression tree and produce a compiled delegate (
BuildExpr<T>/CompileRule<T,TResult>, OP-CIA-03). - Provide static factory methods (
PropertyRule,MethodRule,EvalRuleOutProperty,EvalRuleOutValue) as the only way to construct aNotificationRule, since its constructor is private (OP-CIA-04).
Component boundaries¶
NotificationMatrix: configuration DTO grouping a set ofNotificationRuleentries under a composite"{DocType}:{SubType}"key (NotificationMatrix.Key).NotificationRule: an immutable-by-construction rule definition (private constructor plus static factories) describing which model member to evaluate, which operator to apply, and what output to produce.NotificationRuleEngine: the static rule-evaluation and expression-compilation engine; it holds no instance state, though the class itself is not declaredstatic.NotificationResult: a DTO pairing the sourceNotificationRulewith its evaluated stringValue.
Interaction model¶
- The caller supplies a model instance of any type
Tand aNotificationMatrix; the engine never constructs or looks up either one itself (no data-access or configuration code exists in this library). - Rule behavior is entirely metadata-driven: member names, operator names, and target values are strings resolved by reflection at run time, so which members of
Ta rule touches is not visible from source. - Expression trees are compiled fresh on every
CompileRule<T,TResult>call, once per rule per model per invocation; compiled delegates are not cached (NotificationRuleEngine.csline 78), which is a tech-debt and performance finding. - A
boolrule whose result is true can recurse into a childPropertyRule(built fromOutProperty/OutPropertyTypeName) that inherits the parent rule'sIdandPosition, so a single logical rule can resolve to a derived property value (OP-CIA-02, rule CIA-BR-005 in Business rules). - This library has no consumers via
<ProjectReference>anywhere in the repository; its only known in-repo consumer,Web/SAIF.Web.Mvc/SAIF.SAIFCode.Web.Mvc.csproj, references the packaged DLL directly rather than the source.
Architecture diagram¶
The following diagram shows the high-level interaction between a caller, the rule engine, and the model being evaluated.
flowchart TD
Caller["Caller supplies model T<br>and NotificationMatrix"] --> Engine["NotificationRuleEngine<br>CalculateNotifications"]
Engine --> Rules["NotificationRule definitions<br>(built via static factories)"]
Engine --> Compile["BuildExpr / CompileRule<br>LINQ expression compilation"]
Compile --> Model["Model T<br>(reflection-resolved member)"]
Model --> Results["NotificationResult array<br>keyed by rule position"]
Results --> Caller
Sequence diagram¶
The following diagram shows the primary evaluate-and-compile sequence for a single rule.
sequenceDiagram
participant Client
participant Engine as NotificationRuleEngine
participant Model as Model T
Client->>Engine: CalculateNotifications(model, matrix)
Engine->>Engine: BuildExpr / CompileRule (per rule)
Engine->>Model: invoke compiled delegate
Model-->>Engine: evaluated value (or null)
Engine-->>Client: NotificationResult[]
Design constraints¶
- No dependency injection, configuration, logging, persistence, or security code exists anywhere in this library; it is a pure in-memory computation component.
NotificationRulehas only a private constructor, so it can only be created through its four static factories; deserializers that require a public default constructor cannot materialize it*.- Expression compilation happens on every call with no delegate cache, which is a known performance characteristic rather than a design choice with mitigations in place.
NotificationMatrix.AlertLegalandAlertCBPexist on the matrix type but are never read by any compiled code in this library; only the uncompiled, non-eligibleClaimDataForOnBaseRuleEngine.csreferences them**.- The source of
NotificationMatrix/NotificationRuledata (for example, an OnBase notification-matrix store) is not visible from this library and could not be traced to any in-repo caller**.
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¶
Services/SAIF.Services.ClaimInfoApi.Core/SAIF.Services.ClaimInfoApi.Core.csprojServices/SAIF.Services.ClaimInfoApi.Core/NotificationMatrix.csServices/SAIF.Services.ClaimInfoApi.Core/NotificationRule.csServices/SAIF.Services.ClaimInfoApi.Core/NotificationRuleEngine.csServices/SAIF.Services.ClaimInfoApi.Core/NotificationRuleResult.cs