SAIF.Framework.Common architecture¶
SAIF.Framework.Common is a foundation utility library at the lowest tier of the SAIF .NET Framework 4 stack. It has zero outbound dependencies on other SAIF assemblies or third-party packages, which makes it safely referenceable by any layer above it. Its responsibility is to supply cross-cutting primitives: date/date-range semantics, string normalization and casing, validation result modelling, argument guards, sequence generation, serialization helpers, exception formatting, and logging contracts (Stage 1 analysis, "Responsibility boundary").
Responsibilities¶
- Supply fail-fast argument/precondition guards (
Enforce,ValidatedNotNullAttribute,GenericExtensions.IsNull/IfNullThrow) (Stage 1 analysis, "Functional groupings"). - Represent and reason about date intervals — validity, overlap, contiguity, open-endedness, membership — plus EDI/Julian date encoding (
IDateRange,DateRange,NullableDateRange,DateRangeExtensions,DateExtensions,DateMaker,Julian) (Stage 1 analysis, "Functional groupings"). - Normalize and classify text: casing, truncation, character-class filtering, Unicode→ASCII folding, truthy-string parsing, decimal precision (
StringExtensions,StringUtilities,TitleCase,BooleanExtensions,NumericExtensions) (Stage 1 analysis, "Functional groupings"). - Model validation outcomes and surface them as an exception (
IValidationResult,ValidationResult,IValidationFailure,ValidationFailure,SaifValidationException) (Stage 1 analysis, "Functional groupings"). - Carry contextual (view-routing) exception information for a consuming presentation layer (
ContextExceptionand its four subclasses) (Stage 1 analysis, "Functional groupings"). - Provide in-memory monotonic sequence generators (
ISequenceGenerator<T>,SequenceGenerator<T>,Sequence,LongSequence) (Stage 1 analysis, "Functional groupings"). - Provide JSON/XML serialization round-tripping, stream-to-byte-array conversion, MD5 hashing, and binary header search (
Serializer,GenericExtensions.ToJsonString/ToXmlString,DotNet40Extensions,FileExtensions,ByteExtensions) (Stage 1 analysis, "Functional groupings"). - Define — but not implement — console/file logging contracts and format exception chains for logs (
ILogWriter,IConsoleLogService,LogType,ExceptionExtensions) (Stage 1 analysis, "Functional groupings"). - Provide strongly-typed reflection helpers for property discovery and assignment (
Reflector,ExpressionExtensions) (Stage 1 analysis, "Functional groupings"). - Provide empty marker contracts for downstream data-entity types (
IDataEntity,EntityBase<TEntity>) (Stage 1 analysis, "Functional groupings"). - Parse ASP.NET MVC-style route segments from a
Uriand splitDOMAIN\useridentity names (UriExtensions,SecurityPrincipalExtensions) (Stage 1 analysis, "Functional groupings"). - Fill LINQ/collection gaps:
ForEach,None,TakeFromEnd, keyedDistinct, full/left outer joins, dictionary merge/upsert (IEnumerableExtensions,DictionaryExtensions) (Stage 1 analysis, "Functional groupings").
Component boundaries¶
- Guard / precondition layer:
Enforce,ValidatedNotNullAttribute,GenericExtensions.IsNull/IfNullThrow— fail-fast argument validation; throwsArgumentNullException/ArgumentException/caller-supplied exception types (Stage 1 analysis, "Functional groupings (layers within the library)"). - Date & date-range domain:
IDateRange,IDateRangeList,DateRange,NullableDateRange,DateRangeExtensions,DateExtensions,IComparableExtensions,DateMaker,Julian,DateRangeOverlapResult,IncludeComparisons,ContiguousOptions,OverlappingDateOptions— represents and reasons about date intervals (Stage 1 analysis, same section). - String & text normalization:
StringExtensions,StringUtilities,TitleCase,BooleanExtensions,NumericExtensions— casing, truncation, character-class filtering, Unicode→ASCII folding, truthy-string parsing, decimal precision (Stage 1 analysis, same section). - Validation modelling:
IValidationResult,ValidationResult,IValidationFailure,ValidationFailure,SaifValidationException— accumulates property-level failures and surfaces them as an exception (Stage 1 analysis, same section). - Contextual (view) exceptions:
ContextException+ 4 subclasses — carries aTargetViewname and aModelpayload so an MVC-style presentation layer can route to a specific error view* (Stage 1 analysis, same section). - Sequence generation:
ISequenceGenerator<T>,SequenceGenerator<T>,Sequence,LongSequence— in-memory monotonic counters (Stage 1 analysis, same section). - Serialization:
Serializer,GenericExtensions.ToJsonString/ToXmlString,DotNet40Extensions,FileExtensions,ByteExtensions— JSON (JavaScriptSerializer) and XML (XmlSerializer) round-tripping to/from files and strings; stream→byte[]; MD5 hashing; binary header search (Stage 1 analysis, same section). - Diagnostics / logging contracts:
ILogWriter,IConsoleLogService,LogType,ExceptionExtensions— define (but do not implement) console/file logging; format exception chains for logs (Stage 1 analysis, same section). - Reflection helpers:
Reflector,ExpressionExtensions— strongly-typed property discovery and assignment (Stage 1 analysis, same section). - Entity markers:
IDataEntity,EntityBase<TEntity>— empty marker contracts for downstream data-entity types (Stage 1 analysis, same section). - Web/URL helpers:
UriExtensions,SecurityPrincipalExtensions— parse ASP.NET MVC-style route segments from aUri; splitDOMAIN\useridentity names (Stage 1 analysis, same section). - Collection helpers:
IEnumerableExtensions,DictionaryExtensions— LINQ gap-fillers:ForEach,None,TakeFromEnd, keyedDistinct, full/left outer joins, dictionary merge/upsert (Stage 1 analysis, same section).
Interaction model¶
- The library is stateless and synchronous. It exposes no long-lived services, no I/O ports other than explicit file paths passed by the caller (
Serializer.LoadFromJson,SaveToXml,DotNet40Extensions.LoadFromJson, andILogWriter.FilePath, which is implemented elsewhere), and no network, database, or configuration access (Stage 1 analysis, "Data and control flow"). - All control flow is caller-driven: a consumer calls a static method or extension method, the method computes a result or throws, and returns (Stage 1 analysis, "Data and control flow").
- The only mutable state is the
CurrentValuefield held by aSequenceGenerator<T>instance and the collections held by aValidationResultinstance (Stage 1 analysis, "Data and control flow"). - There are no outbound cross-layer dependencies. Inbound, the library is designed to be consumed by SAIF application and component layers, evidenced by the ASP.NET MVC-shaped helpers (
UriExtensions.ControllerAndActionNamedefaults to"Home/Index",ContextException.TargetView), the console-logging contracts (IConsoleLogService), and the EDI/Julian date encoders that target mainframe file interchange formats* (Stage 1 analysis, "Cross-layer dependencies"). ILogWriterandIConsoleLogServicehave no implementations in this library — they are contracts intended for consumers/other libraries to implement (Stage 1 analysis, "Interfaces (contracts)").
Architecture diagram¶
The following diagram shows the library's internal functional groups, their intra-library couplings, the consuming applications outside this repository, and the .NET Framework 4.6.2 BCL surfaces they call into (Stage 1 analysis, "Architecture diagram").
flowchart TD
subgraph Consumers["Consuming applications / components (outside this repo)"]
C1["MVC / Web apps"]
C2["Console batch apps"]
C3["Component libraries"]
end
subgraph Lib["SAIF.Framework.Common (assembly)"]
G["Guards<br>Enforce, GenericExtensions"]
D["Date domain<br>IDateRange, DateRange,<br>DateRangeExtensions,<br>DateMaker, Julian, NullableDateRange"]
S["Text<br>StringExtensions,<br>StringUtilities, TitleCase"]
V["Validation<br>IValidationResult, ValidationResult,<br>ValidationFailure,<br>SaifValidationException"]
X["Context exceptions<br>ContextException + subclasses"]
Q["Sequences<br>ISequenceGenerator, SequenceGenerator,<br>Sequence, LongSequence"]
Z["Serialization / bytes<br>Serializer, DotNet40Extensions,<br>FileExtensions, ByteExtensions"]
L["Logging contracts<br>IConsoleLogService, ILogWriter, LogType"]
R["Reflection<br>Reflector, ExpressionExtensions"]
W["Web / identity<br>UriExtensions,<br>SecurityPrincipalExtensions"]
E["Collections<br>IEnumerableExtensions,<br>DictionaryExtensions"]
end
subgraph BCL[".NET Framework 4.6.2 BCL"]
B1["System / System.Core"]
B2["System.Web.Extensions<br>JavaScriptSerializer"]
B3["System.Xml<br>XmlSerializer"]
B4["System.Security.Cryptography / Principal"]
end
C1 --> Lib
C2 --> Lib
C3 --> Lib
S --> G
D --> S
E --> G
W --> G
V --> G
Z --> B2
Z --> B3
Z --> B4
Lib --> B1
Sequence diagram¶
The following diagram shows the primary interaction pattern: a caller invokes a static method or extension method, which computes a result synchronously and returns or throws — the library holds no long-lived state beyond a SequenceGenerator<T> instance's CurrentValue or a ValidationResult instance's collections (Stage 1 analysis, "Data and control flow").
sequenceDiagram
participant Caller
participant Component as "SAIF.Framework.Common component<br>(static class / extension method)"
Caller->>Component: Invoke static/extension method
Component-->>Caller: Return computed result
Component--xCaller: or throw an exception
Design constraints¶
- The library declares zero
<ProjectReference>and zero<PackageReference>entries, and its.nuspecdeclares no<dependencies>; it is a leaf with no in-repo or NuGet dependencies, which is what allows it to be safely referenced from any layer above it (Stage 1 analysis, "Internal (repository) dependencies", "NuGet / package dependencies"). - There is a circular namespace dependency between
SAIF.Common.ExtensionsandSAIF.Common.Utility:StringExtensionscallsTitleCase, andTitleCasecalls back intoStringExtensions/IEnumerableExtensions. This is legal in a single assembly but is a design coupling worth noting (Stage 1 analysis, "Intra-library coupling"). IncludeComparisonsis declared twice with identical members (once inSAIF.Common, once inSAIF.Common.Extensions), andContiguousOptions/OverlappingDateOptionseach have a duplicate/near-duplicate nested counterpart inDateRangeExtensions; a consumer importing both namespaces risks compile-time ambiguity or passing the wrong enum type* (Stage 1 analysis, "Duplicate and ambiguous public types").- Namespace and folder layout are not aligned:
Classes/Enforce.csdeclares namespaceSAIF; mostClasses/*.csdeclareSAIF.Common; onlyContextException.csandNullableDateRange.csdeclareSAIF.Common.Classes;Interfaces/likewise splits betweenSAIF.CommonandSAIF.Common.Interfaces* (Stage 1 analysis, "Namespaces", "Duplicate and ambiguous public types"). TitleCaseisinternalwhile its siblingStringUtilitiesin the same namespace ispublic; the title-casing acronym/word lists are therefore reachable only throughStringExtensions.ToTitleCaseand cannot be extended by a consumer without a source change and rebuild* (Stage 1 analysis, "Duplicate and ambiguous public types").- Two areas of behavior depend on ambient runtime state rather than configuration:
StringExtensions.ToProperCase/ToTitleCasefollow the current thread culture (Thread.CurrentThread.CurrentCulture.TextInfo), and several date operations (DateExtensions.IsCurrentDate/IsFutureDate/IsPastDate,DateRangeExtensions.IsFutureRange/IsPastRange,Julian.GetYear) depend on the server clock and time zone (Stage 1 analysis, "Ambient runtime state consumed"). Extensions/DotNet35Extensions.csexists on disk but has no<Compile Include>entry, so it is excluded from the compiled assembly even though the.nuspecships it as source, meaning a consumer browsing package sources will see a type that does not exist at runtime* (Stage 1 analysis, "Build and packaging discrepancies", "nuspec contents").- No automated test project exists under
Common/SAIF.Common/, andSAIF.Framework.Common.slncontains only the one project (Stage 1 analysis, "Unknowns that cannot be resolved from this repository").
Related documentation¶
Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.
Sources¶
Common/SAIF.Common/SAIF.Framework.Common.csprojSAIF.Framework.Common.slnCommon/SAIF.Common/Classes/Enforce.csCommon/SAIF.Common/Extensions/StringExtensions.csCommon/SAIF.Common/Utility/TitleCase.csCommon/SAIF.Common/Extensions/DateRangeExtensions.csCommon/SAIF.Common/Classes/DateRange.csCommon/SAIF.Common/Extensions/ExceptionExtensions.csCommon/SAIF.Common/Interfaces/IConsoleLogService.csCommon/SAIF.Common/Interfaces/ILogWriter.cs