Skip to content

[Add] uml-like metadata decorators on the model; fixes #27#78

Merged
samatstariongroup merged 4 commits into
developmentfrom
add-model-metadata-decorators
Jun 6, 2026
Merged

[Add] uml-like metadata decorators on the model; fixes #27#78
samatstariongroup merged 4 commits into
developmentfrom
add-model-metadata-decorators

Conversation

@samatstariongroup

@samatstariongroup samatstariongroup commented Jun 6, 2026

Copy link
Copy Markdown
Member

Summary

Implements #27 — add UML-like metadata to the model classes and properties (as done in the COMET-SDK / uml4net) so that ReqIF metamodel relationships are self-documenting.

Two decorators are introduced under ReqIFSharp/Decorators, modelled on uml4net's Decorators but reduced to what ReqIF actually models and prefixed with ReqIf to avoid collisions (e.g. with NUnit.Framework.PropertyAttribute):

  • ReqIfClassAttribute (used as [ReqIfClass(...)]) — name (the ReqIF metaclass / XML element name) and isAbstract.
  • ReqIfPropertyAttribute (used as [ReqIfProperty(...)]) — aggregation (containment vs reference), lowerValue/upperValue multiplicity, isOrdered, isReadOnly, isDerived, isDerivedUnion, isUnique, defaultValue.
  • AggregationKind enum (None / Shared / Composite).

[ReqIfClass] is applied to all 54 model classes and [ReqIfProperty] to every metamodel property, with multiplicity and aggregation values sourced from the embedded reqif.xsd. The decorators live in the ReqIFSharp namespace, so no extra using is needed on the model classes.

Per the issue scope, uml4net's Implements / Subsetted / RedefinedBy / RedefinedProperty decorators were not ported — ReqIFSharp has no interfaces or UML generalization-sets to attach them to. An xmiId field was also omitted (ReqIFSharp does not round-trip XMI).

Explicit arguments at every use-site

Every decorator usage passes all constructor arguments explicitly — including the optional ones that would otherwise fall back to defaults — so the metadata is fully self-documenting where it is applied:

[ReqIfClass(name: "SPEC-OBJECT", isAbstract: false)]
public class SpecObject : SpecElementWithAttributes

[ReqIfProperty(aggregation: AggregationKind.None, lowerValue: 1, upperValue: 1, isOrdered: false, isReadOnly: false, isDerived: false, isDerivedUnion: false, isUnique: true, defaultValue: null)]
public SpecObjectType Type { get; set; }

Concrete classes carry isAbstract: false and abstract bases isAbstract: true; all 87 [ReqIfProperty] usages list the full nine-argument set.

Completeness guard

ModelMetadataTestFixture is a reflection-driven test that fails if any model class or metamodel property is left undecorated, or if multiplicity is inconsistent (Upper >= Lower, Upper >= 1). Container back-references (e.g. DocumentRoot, ReqIFContent, Owner) and polymorphic convenience accessors (ObjectValue, the base Type/Definition aliases) are in a documented exclusion list. This keeps future model additions honest.

(Note: explicitness itself cannot be asserted by reflection — explicitly-passed default arguments and omitted ones compile to identical attribute metadata — so it is maintained as a source convention.)

Verification

  • dotnet build ReqIFSharp.sln -c Release — 0 warnings / 0 errors on netstandard2.0.
  • dotnet test ReqIFSharp.sln376 tests pass (292 core incl. 10 new decorator tests, 84 extensions).
  • The decorators are inert metadata; (de)serialization behaviour is unchanged.

Notes

  • 48 model files annotated; 3 new decorator source files (ReqIfClassAttribute, ReqIfPropertyAttribute, AggregationKind); 3 new test fixtures.
  • No .csproj/version changes.
  • The ReqIf prefix on both decorators avoids the NUnit.Framework.PropertyAttribute collision entirely, so no test-side using alias is required.

Adds ClassAttribute and PropertyAttribute decorators (plus an AggregationKind enum) under ReqIFSharp/Decorators, modelled on uml4net's Decorators, and applies them to all 54 model classes so the ReqIF metamodel (abstractness, multiplicity, containment vs reference) is self-documenting. Multiplicity and aggregation values are sourced from the embedded reqif.xsd.

A reflection-driven ModelMetadataTestFixture guards completeness: it fails if any model class or metamodel property is left undecorated, with a documented exclusion list for container back-references and convenience accessors. The decorators are inert metadata, so serialization behaviour is unchanged.
…id NUnit collision

ReqIFSharp.PropertyAttribute collided with NUnit.Framework.PropertyAttribute in the test assembly, requiring a using-alias. Renaming the decorator to ReqIfPropertyAttribute (used as [ReqIfProperty(...)]) removes the collision entirely; the test-side alias is no longer needed. ClassAttribute is unchanged as it has no such collision.
Mirrors the ReqIfPropertyAttribute rename so both model decorators share the ReqIf prefix. Applied to all 48 model classes as [ReqIfClass(...)] and the test fixtures updated accordingly.
Every [ReqIfClass] and [ReqIfProperty] usage now passes all constructor arguments explicitly, including the optional ones that previously fell back to defaults (isOrdered/isReadOnly/isDerived/isDerivedUnion/isUnique/defaultValue on properties; isAbstract on concrete classes). Values are unchanged - this is a readability change so the metadata is self-documenting at the use-site.
@sonarqubecloud

sonarqubecloud Bot commented Jun 6, 2026

Copy link
Copy Markdown

@samatstariongroup samatstariongroup merged commit e721610 into development Jun 6, 2026
8 checks passed
@samatstariongroup samatstariongroup deleted the add-model-metadata-decorators branch June 6, 2026 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant