This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
ReqIFSharp is a .NET library to deserialize (read) and serialize (write) OMG ReqIF requirements-interchange documents. The repository ships two NuGet packages:
- ReqIFSharp — the core object model plus (de)serializers. Targets
netstandard2.0. - ReqIFSharp.Extensions — query/convenience extension methods and the
ReqIFLoaderService, built on top of the core. Targetsnetstandard2.0.
The two packages version independently (e.g. ReqIFSharp 10.x, ReqIFSharp.Extensions 5.x).
Test projects target net10.0 and use NUnit. LangVersion is pinned to 14.0 (in Directory.Build.props).
Building requires the .NET 10 SDK (global.json, rolls forward to the latest 10.0 feature band).
MSBuild layout. Directory.Build.props holds settings for every project (company,
copyright, repository, LangVersion, GenerateDocumentationFile). Packaging settings shared
by the published libraries (package metadata, README/LICENSE/NOTICE pack items, the
Microsoft.Sbom.Targets reference) live in Directory.Build.targets, guarded by
'$(IsPackable)' != 'false'; it must be a .targets file because IsPackable is set in the
project body, after .props is evaluated. GenerateDocumentationFile cannot move there: the
SDK derives the documentation-file settings from it before .targets is evaluated. Test
projects therefore set both <IsPackable>false</IsPackable> and
<GenerateDocumentationFile>false</GenerateDocumentationFile>. The library .csproj files keep
only per-package settings (version, title, description, id, icon, authors, release notes).
dotnet build ReqIFSharp.sln -c Release
dotnet test ReqIFSharp.sln # all tests
dotnet test ReqIFSharp.Tests/ReqIFSharp.Tests.csproj # one project
dotnet test --filter "FullyQualifiedName~ReqIFDeSerializerTestFixture" # one fixture
dotnet test --filter "Name=YourTestMethod" # one test
# coverage (opencover format, see coverlet.runsettings)
dotnet test ReqIFSharp.sln --settings coverlet.runsettingsObject graph. ReqIF is the document root (ReqIF.cs). It holds a ReqIFHeader
and a ReqIFContent (the CoreContent), which in turn contains datatypes, spec types,
spec objects, specifications, and relations. Most domain classes derive from
Identifiable / AccessControlledElement and know how to read and write themselves
via internal ReadXml/WriteXml(Async) methods — serialization logic lives on the
model classes, not in a central mapper.
Deserialize / serialize. ReqIFDeserializer (IReqIFDeSerializer) and
ReqIFSerializer (IReqIFSerializer) are the public entry points. Both handle a plain
.reqif XML file/stream or a .reqifz zip archive that may contain multiple ReqIF
documents plus embedded external objects — hence the APIs operate on
IEnumerable<ReqIF> and take a SupportedFileExtensionKind. Every operation has a sync
and an ...Async (CancellationToken) variant; keep both in sync when changing
serialization behavior.
Polymorphic XML mapping. ReqIfFactory (internal, static) is the single place that
maps concrete subtypes (attribute definitions, datatypes, attribute values, spec types)
to/from their ReqIF XML element names. When adding a new concrete model subtype, update
ReqIfFactory in addition to the class's own ReadXml/WriteXml.
Schema validation. The full ReqIF + XHTML XSD set is embedded as resources in
ReqIFSharp/Resources (see EmbeddedResource entries in ReqIFSharp.csproj).
ReqIfSchemaResolver resolves XSD imports against these embedded resources so
validation works without filesystem access. Deserialization can optionally validate and
report through a ValidationEventHandler.
Original-XML round-tripping. ReqIF retains the XML attributes/namespaces seen on
read so re-serialization reproduces the original document's namespace declarations.
Preserve this when touching read/write of the root element.
Logging / DI. Core types take an optional ILoggerFactory and fall back to
NullLogger when none is supplied — there is no other DI container. Test projects wire
Serilog into Microsoft.Extensions.Logging and assert on log output via
TestLogEventSink.
ReqIFSharp.Extensions. ReqIFExtensions/*Extensions.cs are stateless query helpers
over the core model (navigating spec hierarchies, resolving attribute values, etc.).
Services/ReqIFLoaderService (IReqIFLoaderService) loads and caches a ReqIF source so
the extensions can be used by consuming applications (e.g. the web viewer).
- Every source file starts with the Starion Group header in short SPDX form: the
<copyright file="..." company="Starion Group S.A.">block holdingSPDX-FileCopyrightText: 2017-2026 Starion Group S.A.andSPDX-License-Identifier: Apache-2.0. Copy it onto any new file, with that file's name. - Tests use NUnit 4 (
[TestFixture]/[Test]); fixtures are named*TestFixture. Sample ReqIF inputs live inReqIFSharp.Tests/TestDataand are copied to output. - Every change that affects users of the packages (feature, fix, dependency update,
breaking change) adds a line under
## [Unreleased]inCHANGELOG.md, in the same pull request. Use the Keep a Changelog groups (Added, Changed, Deprecated, Removed, Fixed, Security), link the issue, start lines that only concern ReqIFSharp.Extensions with "ReqIFSharp.Extensions:", and mark breaking changes with Breaking:. - On release, rename
[Unreleased]to[X.Y.Z] - YYYY-MM-DD, add a fresh empty[Unreleased], update the links at the bottom of the file, and copy the entries into<PackageReleaseNotes>of the affected.csprojfiles. - Contributions require a signed CLA (see
CLA/);developmentis the main branch.