SAIF.NetCore.Common architecture¶
SAIF.NetCore.Common is a foundation-layer, general-purpose utility library of stateless static extension and helper classes, plus a small set of value/exception types for date ranges, validation results, and MVC-oriented context exceptions; it has zero SAIF and zero third-party package dependencies, and no library in this repository currently consumes it.
Responsibilities¶
- Provide BCL-type extension methods for strings, dates, date ranges, dictionaries, enumerables, bytes, URIs, generics, comparables, expressions, numerics, and security principals (
Extensionsnamespace). - Provide small static helper classes:
DateMaker(EDI-style date strings),Enforce(argument guard clauses),Julian(Julian-date conversions), andReflector(property-info reflection) (Helpersnamespace). - Provide a validation-result model (
ValidationResult,ValidationFailure) and aSaifValidationExceptionfor surfacing validation failures. - Provide MVC-oriented context exception types (
ContextExceptionand its four subclasses) whoseTargetViewvalues imply ASP.NET MVC view-routing intent in consuming applications*. - Provide
DateRange/NullableDateRangevalue types and a sequence-generator type hierarchy (SequenceGenerator<T>,LongSequence,Sequence). - Provide shared enums (
ContiguousOptions,DateRangeOverlapResult,IncludeComparisons,LogType,OverlappingDateOptions) for consumers, several of which duplicate nested enums defined on the extension classes themselves.
Component boundaries¶
Extensions: 15 static extension classes, each scoped to one BCL type or concern (string, date, date-range, dictionary, exception, expression, file, generic, comparable, enumerable, numeric, security-principal, URI, boolean, byte). No class holds mutable instance state.Helpers: 4 public static helper classes plus one internal marker attribute (ValidatedNotNullAttribute) used only as a code-analysis hint onEnforce.ArgumentNotNull.InternalUtility.TitleCase: aninternalengine class that backsStringExtensions.ToTitleCase; it is not part of the public surface.Types: 14 public types — exception hierarchies (ContextExceptionand subclasses,SaifValidationException), value types (DateRange,NullableDateRange), an empty placeholder (EntityBase<TEntity>), and the sequence-generator hierarchy (SequenceGenerator<T>,LongSequence,Sequence).Enums: 5 top-level enums, three of which (ContiguousOptions,IncludeComparisons,OverlappingDateOptions) are shadowed by functionally identical enums declared elsewhere in the assembly and are not bound by the library's own call sites*.- There is no DI, hosting, or configuration surface anywhere in this library: no
IServiceCollection,IHostBuilder,IApplicationBuilder,IConfiguration,IOptions, environment-variable, or registry access exists in any of its 35 compiled files.
Interaction model¶
- This library has no SAIF package dependency and is consumed by no library currently present in this repository;
Architecture.mddescribes it as available for "any library (including contracts consumers) can use without pulling in the rest of the framework", but no current.csprojundersrc/exercises that path*. - Internally, control flow is one-directional in most places but has one same-assembly cross-namespace cycle:
Extensionsclasses callHelpers.Enforce.ArgumentNotNullfor guard clauses, whileEnforce's own members (IsNullOrWhiteSpace,IsNull,IsNullOrEmpty,IfNullThrow) call back intoExtensionsmethods. This is a mutual dependency between namespaces inside one assembly, not a cross-package cycle. Extensions.StringExtensions.ToTitleCasedelegates to theinternalInternalUtility.TitleCaseengine, which in turn calls back into severalExtensionsmembers (IsNullOrEmpty,ToStringAll,IsIn,ToLower(string[]),TakeFromEnd,ToProperCase,ContainsOnlyNumericCharacters).Extensions.DateRangeExtensionsoperates onTypes.DateRangeand callsIComparableExtensions.IsBetweenandDateExtensions.IsMinOrMax;Types.NullableDateRange.GetOverlapStatereturns theEnums.DateRangeOverlapResultenum;Types.SaifValidationExceptioncarries aTypes.ValidationResult, which carries a list ofTypes.ValidationFailure.- If a consuming library were to reference this package (per the README's stated intent and
Architecture.md's "sometimes" wording), it would do so as a sibling NuGet reference alongsideSAIF.NetCore.ServiceContracts, not as a replacement for it. This contradicts the README's own statement that the package "should never be a dependency of the NetCore.Services packages"; the discrepancy between the README andArchitecture.mdremains unresolved in available source materials.
Architecture diagram¶
The following diagram shows the internal namespace structure of this foundation-layer library and its (currently theoretical) relationship to the rest of the framework.
flowchart TD
subgraph COMMON["SAIF.NetCore.Common (foundation layer)"]
EXT["Extensions<br>(15 static extension classes)"]
HLP["Helpers<br>(DateMaker, Enforce, Julian, Reflector)"]
INT["InternalUtility.TitleCase<br>(internal)"]
TYP["Types<br>(DateRange, ValidationResult,<br>ContextException, sequences)"]
ENM["Enums<br>(5 top-level enums)"]
end
EXT -->|ArgumentNotNull| HLP
HLP -->|guard predicates| EXT
EXT -->|ToTitleCase| INT
INT -->|string helpers| EXT
EXT -->|DateRangeExtensions| TYP
TYP -->|GetOverlapState result| ENM
OTHER["Other SAIF.NetCore.* libraries<br>(no current consumer in this repo)"] -.->|NuGet ref, if adopted| COMMON
Sequence diagram¶
The following diagram shows a representative call sequence for the one documented cross-namespace cycle in this library: an Extensions call that delegates to Enforce and back.
sequenceDiagram
participant Caller as Consumer code
participant Ext as Extensions<br>(DictionaryExtensions)
participant Enforce as Helpers.Enforce
Caller->>Ext: UpdateOrAdd(dictionary, key, value)
Ext->>Enforce: ArgumentNotNull(dictionary, "dictionary")
Enforce->>Enforce: dictionary.IsNull()
alt dictionary is null
Enforce-->>Ext: throws ArgumentNullException
Ext-->>Caller: propagates ArgumentNullException
else dictionary is non-null
Enforce-->>Ext: returns dictionary
Ext->>Ext: ContainsKey(key)? set existing or Add(key, value)
Ext-->>Caller: returns value
end
Design constraints¶
- No project references between libraries in this repository; this library takes zero package references of any kind, SAIF or third-party, consistent with its foundation-layer, zero-dependency position in
Architecture.md. - Nearly every helper and extension class is
staticand stateless, with one documented exception:DateRange.Emptyis a shared static instance whoseBeginDate/EndDatehave public setters, so any consumer that mutates it changes the value process-wide*. - Several members read
DateTime.Now/DateTime.Todayor the current thread culture directly (DateExtensions,DateRangeExtensions.IsFutureRange/IsPastRange,Julian.GetYear,StringExtensions.ToProperCase,DateRange.Parse/ToString), so their results depend on server clock, time zone, and locale. DateRangeExtensions.IsOverLapping(IEnumerable<DateRange>)throwsNullReferenceExceptionfor any input of 2 or more ranges because of an unconditionalswitchdereference on the first loop iteration, and any==/!=comparison of aDateRangeagainstnullthrows for the same underlying reason — both are known defects rather than intended behavior*.- The code shows heritage from a .NET Framework/VB.NET predecessor (
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]/[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "d")]-style attributes, aDateRange.csheader mentioning removed "SmartDate"/VB-style code, and a<RepositoryUrl>still pointing at the legacy TFS repository), which is reflected in some naming and design choices*.
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. Statements marked with**could not be confirmed; treat as unknown until verified.
Sources¶
src/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common.csprojsrc/SAIF.NetCore.Common/README.mdsrc/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Extensions/—DictionaryExtensions.cs,StringExtensions.cs,DateRangeExtensions.cs,IEnumerableExtensions.cs,UriExtensions.cs,IComparableExtensions.cssrc/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Helpers/Enforce.cssrc/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/InternalUtility/TitleCase.cssrc/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Types/—DateRange.cs,NullableDateRange.cs,ContextException.cs,SaifValidationException.cs,ValidationResult.cs,ValidationFailure.cs,EntityBase.cs,SequenceGenerator.cs,LongSequence.cs,Sequence.cssrc/SAIF.NetCore.Common/SAIF.NetCore.Common/SAIF.NetCore.Common/Enums/—ContiguousOptions.cs,DateRangeOverlapResult.cs,IncludeComparisons.cs,LogType.cs,OverlappingDateOptions.csArchitecture.md