SAIF.Framework.Common.Files architecture¶
SAIF.Framework.Common.Files (project folder Common\SAIF.Common.Files, root namespace SAIF.Common.Files) is a .NET Framework 4.6.2 class library containing two cohesive, mutually independent subsystems — an attribute/fluent-configuration-driven flat-file reader/writer and an ASC X12 EDI object model — that share only the IParser<T> contract and a dependency on the SAIF.Framework.Common package.
Responsibilities¶
- Read and write delimited (CSV, tab-delimited, custom-delimiter) and fixed-width flat files by mapping file rows to POCO record types via declarative attributes or a fluent, code-first configuration API.
- Model, parse, build, and serialise ASC X12 EDI interchange files, including the envelope hierarchy (interchange → functional group → transaction set → hierarchical transaction → hierarchical level) and ~40 strongly-typed segment classes for healthcare transactions (837 claim, 835 remittance, 277 claim status, 997/999 acknowledgement)*.
- Provide a shared, minimal
IParser<T>contract (List<T> Parse(string)) used by both the flat-file record parsing path and the EDI segment/element parsers. - Delegate cross-cutting utility behaviour (sequential indexing, argument validation, string/enumerable/expression helpers) to the same-repo
SAIF.Framework.Commonpackage rather than reimplementing it.
Component boundaries¶
- Flat-file subsystem (
SAIF.Common.Files.Core) — a reflection- and attribute-driven mapper between delimited/fixed-width text lines and POCO record types. - Declaration layer (
Core\Attributes\):FormatBaseand concrete attributes (Csv,TabDelimited,DelimitedBy,FixedFormat,DelimitedLayout,FixedLayout) declare format and per-property layout. - Configuration layer (
Core\Configurations\):FileConfiguration/FileConfiguration<T>,FileRecordLayout, andFileLayoutBuilderhold the runtime layout model and expose an alternative fluent (code-first) configuration path. - Engine layer (
Core\FileReader.cs,Core\FileWriter.cs): static generic classes that discover configurations, prepareMicrosoft.VisualBasic.FileIO.TextFieldParser, and iterate/build records. Both privately re-implement an identical attribute-scan method (GetFileConfigurations()), which is duplicated rather than shared.* - Record model (
Core\Record.cs,TabDelimitedRecord.cs,Field.cs):Record,TabDelimitedRecord, andFieldcarry the rawValue/Indexdata. - EDI subsystem (
SAIF.Common.Files.Ediand nestedEdi.Core.*/Edi.Segments) — an object model over ASC X12 interchange files. - Entry/facade:
EdiManager.File()→IEdiFileBuilder/EdiFileBuilder;.Path(path).Read()/.Write(file)is the sanctioned entry point for file IO. - IO layer (
Edi\Core\Readers,Edi\Core\Writers):EdiFileReaderandEdiFileWriter. - Lexical parsing layer (
Edi\Core\Parsers):EdiSegmentParser→EdiDataElementParser→EdiCompositeDataElementParser, cascading on~,*, and:respectively. - Structural parsing layer:
EdiGroupParserconverts a flat, index-ordered segment list into the X12 envelope hierarchy (file → functional groups → transaction sets → hierarchical transactions → hierarchical levels). - Domain model (
SAIF.Common.Files.Edi):EdiFile,EdiSegment,EdiElement,SegmentGroup,FunctionalGroup,TransactionSet,HierarchialTransaction,HierarchialLevel. - Builders (
Edi\Core\Builders):SegmentBuilderis the only writer of element indexes;EdiRecordBuilderis the only serialiser. - Typed segment layer (
Edi\Segments): ~43 typed segment classes implementingISegmentData(symmetricBuild()/Fill()), depending on the element model but never on the parsers or on IO. - Shared dependency boundary: both subsystems depend on the same-repo
SAIF.Framework.CommonNuGet package forSequence,Enforce, and string/enumerable/expression extensions, but do not depend on each other beyond the sharedIParser<T>contract.
Interaction model¶
- The domain model never performs file IO itself; IO is isolated in
Edi\Core\Readers/Edi\Core\WritersandCore\FileReader/FileWriter. - The typed segment layer depends on the element model but never on the parsers or on IO.
EdiFileis the one place where the model calls back into a parser (EdiGroupParser.CreateFunctionalGroups) — a lazy-initialisation/cycle point between the model and parser layers.- Reading an EDI file:
EdiManager.File().Path(p).Read()→EdiFileReader.Read()concatenates all lines into one continuous string →EdiSegmentParser.Parse→ cascading element/composite parsers →EdiFile.SetSegments→EdiFile.RefreshGroupings()builds the header/trailer and (whenISA/IEA/GS/GEare all present) the functional-group hierarchy viaEdiGroupParser. - Writing an EDI file: typed segments produce elements via
ISegmentData.Build();SegmentBuilderassembles ordered elements (rejecting a duplicate identifying element at index 0, omitting nulls);EdiRecordBuilderserialises segments/elements to text, preserving skipped-element ordinals with*placeholders;EdiFileWriterwrites the result as a single~-terminated line, overwriting any existing file. - Reading a typed flat file:
FileReader<TRecord>.ReaddiscoversFormatBase/layout attributes onTRecord, selects a configuration (single, or the one flaggedIsDefault), preparesTextFieldParseraccordingly, then iterates rows and builds each record via the layout's readable properties, converters, and the delegatedSequenceindexer. - Writing a typed flat file:
FileWriter<TRecord>.Writeperforms the same configuration discovery, then serialises an optional header record and each data record through writable layouts, converters, and fixed-width alignment/padding. - Both subsystems' parser/reader classes are single-use instances — each parser instance carries its own results list and index sequence.*
Architecture diagram¶
The following diagram shows the two independent subsystems and their shared dependency on SAIF.Framework.Common.
flowchart TD
subgraph FlatFile["Flat-file subsystem<br>(SAIF.Common.Files.Core)"]
Attr["Attributes<br>Csv / TabDelimited /<br>DelimitedBy / FixedFormat<br>DelimitedLayout / FixedLayout"]
Cfg["Configurations<br>IFileConfiguration /<br>FileConfiguration<T><br>FileRecordLayout / FileLayoutBuilder"]
RW["FileReader<TRecord> /<br>FileWriter<TRecord><br>FileReader (untyped)"]
Rec["Record model<br>IRecord / Record / IDelimitedRecord<br>TabDelimitedRecord / Field"]
Attr --> Cfg
Cfg --> RW
RW --> Rec
RW --> TFP["Microsoft.VisualBasic.FileIO.<br>TextFieldParser"]
end
subgraph Edi["EDI subsystem (SAIF.Common.Files.Edi)"]
Mgr["EdiManager / EdiFileBuilder"]
IO["EdiFileReader / EdiFileWriter"]
Parse["Parsers<br>EdiSegmentParser / EdiDataElementParser<br>EdiCompositeDataElementParser<br>EdiGroupParser"]
Model["Domain model<br>EdiFile / EdiSegment / EdiElement<br>SegmentGroup / FunctionalGroup<br>TransactionSet / HierarchialTransaction<br>HierarchialLevel"]
Build["Builders<br>SegmentBuilder / EdiRecordBuilder"]
Seg["Typed segments (ISegmentData)<br>ISA GS ST BHT HL CLP SVC TRN,<br>and 35 more (see API reference)"]
Mgr --> IO
IO --> Parse
Parse --> Model
Seg --> Build
Build --> Model
Model --> Seg
IO --> Build
end
Common["SAIF.Framework.Common (NuGet, same-repo)<br>Sequence / Enforce /<br>string + enumerable +<br>expression extensions"]
FlatFile --> Common
Edi --> Common
Sequence diagram¶
The following diagram shows the primary read/write sequence for an EDI interchange file, from the facade entry point through parsing and grouping.
sequenceDiagram
participant Caller
participant EdiManager
participant EdiFileBuilder
participant EdiFileReader
participant EdiSegmentParser
participant EdiFile
participant EdiGroupParser
Caller->>EdiManager: File()
EdiManager-->>Caller: IEdiFileBuilder
Caller->>EdiFileBuilder: Path(path).Read()
EdiFileBuilder->>EdiFileReader: Read()
EdiFileReader->>EdiFileReader: File.ReadAllLines + concatenate
EdiFileReader->>EdiSegmentParser: Parse(fileData)
EdiSegmentParser-->>EdiFileReader: List<IEdiSegment>
EdiFileReader->>EdiFile: SetSegments(segments)
EdiFile->>EdiFile: RefreshGroupings()
EdiFile->>EdiGroupParser: CreateFunctionalGroups(this)
EdiGroupParser-->>EdiFile: IFunctionalGroupContainer
EdiFileReader-->>EdiFileBuilder: EdiFile
EdiFileBuilder-->>Caller: EdiFile
Design constraints¶
DateMakeris declared in namespaceSAIF.Commondespite living underEdi\Core\, so it appears to consumers as part of the baseSAIF.Commonnamespace rather than the EDI subsystem.*DateTimeBuilder(internal,Edi\Core\Builders\) duplicatesDateMaker.MakeDateTimeand is never called from live code — dead code.*FileFormats.MultipleRecordis declared but never handled byPrepareParseror any writer branch — an unimplemented format.IEdiEntity,IDataElementBuilder,Areas,RequirementDesignator,RelationalCondition,DataElementType,SegmentGroupTypeare declared but not referenced by any live code in this library — reserved/unused contracts.*- No type in this library derives from a BOF base class (
clsBusinessBase,clsBusinessCollectionBase,AppManager), and none derives from an NHibernate, Autofac, or console-framework base type. - Nothing in the library depends on configuration files, a database, a service container, or an identity/authorization API — configuration, security/authorization, and database interactions were all found to be none.
- The library ships its own C# source under
srcvia its.nuspec(<files><file src="**\*.cs" exclude="packages\**\*.*;obj\**\*.*" target="src"/></files>), andIncludeReferencedProjects = truehas no additional bundling effect because the.csprojdeclares no<ProjectReference>elements;SAIF.Framework.Commonis consumed purely as a package dependency.
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.Files\SAIF.Framework.Common.Files.csproj
- Common\SAIF.Common.Files\Core\FileReader.cs
- Common\SAIF.Common.Files\Core\FileWriter.cs
- Common\SAIF.Common.Files\Edi\EdiManager.cs
- Common\SAIF.Common.Files\Edi\EdiFile.cs
- Common\SAIF.Common.Files\Edi\Core\Readers\EdiFileReader.cs
- Common\SAIF.Common.Files\Edi\Core\Writers\EdiFileWriter.cs
- Common\SAIF.Common.Files\Edi\Core\Parsers\EdiSegmentParser.cs
- Common\SAIF.Common.Files\Edi\Core\Parsers\EdiGroupParser.cs
- Common\SAIF.Common.Files\Edi\Core\Builders\SegmentBuilder.cs
- Common\SAIF.Common.Files\Edi\Core\Builders\EdiRecordBuilder.cs
- Common\SAIF.Common.Files\Edi\Core\DateMaker.cs
- Common\SAIF.Common.Files\Edi\Core\Builders\DateTimeBuilder.cs
- Common\SAIF.Common.Files\Core\Enums.cs
- Common\SAIF.Common.Files\Edi\IEdiEntity.cs
- Common\SAIF.Common.Files\Edi\Core\Builders\IDataElementBuilder.cs
- Common\SAIF.Common.Files\Edi\enums.cs