XP One nuget per quantity - #1181
Closed
angularsen wants to merge 2 commits into
Closed
Conversation
TEMP Remove all but 7 SI quantities Add Duration and Length projects TEMP Remove non-SI unit definitions Add UnitsNet.SI, move SI stuff there Include the 8 quantity projects in solution
Closed
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
angularsen
commented
Jul 16, 2023
OwnerAuthor
test comment |
angularsen
commented
Jul 16, 2023
OwnerAuthor
test 2 |
angularsen
commented
Jul 16, 2023
OwnerAuthor
test 3 |
angularsen
commented
Jul 16, 2023
OwnerAuthor
test 4 |
angularsen
commented
Jul 16, 2023
OwnerAuthor
test 5 |
angularsen added a commit
that referenced
this pull request
Jul 30, 2026
## Motivation Explore a source-generated UnitsNet architecture where consumers generate only the built-in and custom quantities they need while retaining strongly typed quantities and units, parsing, conversion, formatting, localization, and quantity relationships. This is inspired by #902 and the ideas explored in #1181. ## Architecture The primary model is consumer-owned generation: - an application owns one generated units assembly and shares those CLR types across its projects; - `UnitsNet.Modular` supplies the runtime, source generator, authoring contracts, and built-in catalog recipes; - built-in recipes generate quantities in `UnitsNet` and unit enums in `UnitsNet.Units` by default, preserving familiar consumer source; - custom definitions retain their declared namespaces, while `[UnitsNetModule("...")]` can explicitly place every selected definition in another namespace; - third parties normally ship definition packages containing public markers, JSON definitions, localizations, conversion expressions, and relationships rather than precompiled quantity structs; - conversion metadata is immutable and generated at compile time; the generated registry supports dynamic discovery without becoming mutable global policy. The POC introduces `UnitsNet.Core` for lean shared contracts, but deliberately leaves the existing `UnitsNet` project and package unchanged. Optional adoption by UnitsNet remains isolated on the stacked `agl/unitsnetgen-poc-unitsnet-integration` branch. ## What this includes - full built-in catalog selection plus named profiles, individual additions, glob filters, and regex filters; - custom UnitsNet-style JSON quantities, localizations, affine/nonlinear conversion functions, and structured relationship files; - generated linear, affine, and logarithmic quantities with typed conversion, parsing, formatting, aggregation, operators, and selected compatibility augmentations; - immutable generated quantity registry and trimming/Native-AOT-friendly System.Text.Json support; - consumer-owned, project-reference, local-NuGet, custom-definition-package, compatibility, lean, representative, and all-SI samples; - consumer-facing README with quick start, project structures, usage examples, and full configuration details; - Rider-friendly direct `AdditionalFiles` flow while retaining `UnitsNetDefinition` and `UnitsNetRelation` item aliases for future reference; - separate `UnitsNet.Modular CI` workflow covering build, tests, isolated NuGet consumption, Native AOT, deterministic packaging, symbols, and Source Link; - independent 6.x alpha MinVer streams using `UnitsNet.Modular/` and `UnitsNet.Core/` tag prefixes, so their minor and patch versions can advance independently. ## Review hardening - synchronized with the current `QuantityValue`-based UnitsNet catalog while retaining intentional `double` storage in this POC; - validates C# identifiers and duplicate unit names as generator diagnostics; - composes prefixes inside the original conversion function, including affine/nonlinear definitions; - diagnoses unknown relation quantity IDs instead of silently dropping recipes; - consolidates unit-system and localized unit resolution through shared operations; - keeps full-catalog compatibility tests tracking `UnitsNet/**` changes intentionally. ## Repository-level footprint The standalone prototype also adds small shared-repository plumbing: `Artifacts/Nugets/.gitkeep`, matching `.gitignore` rules, a repository-local source in `nuget.config`, the `RepositoryLocalNuGetFeed` property in `Directory.Build.props`, central package versions in `Directory.Packages.props`, and local-feed cleanup support in `Build/build-functions.psm1` and `Build/clean.ps1`. These make local package output discoverable on a clean checkout and are not consumer-facing package requirements. ## Deliberate boundaries - Binary compatibility between generated structs and `UnitsNet.dll` is not promised; source compatibility for common concrete APIs is the target. - Mutable `UnitsNetSetup`-style runtime conversion configuration is not reproduced. - Specialized feet/inches parsing and pressure/elevation modeling remain explicit, tested exclusions. - Configurable numeric storage types remain outside this PR so that experiment can be reviewed independently. ## Validation - Release restore and build of `UnitsNet.Modular.slnx` - 108 tests passed: 35 runtime, 30 generator, and 43 full-catalog compatibility tests - local NuGet flow packed matching `UnitsNet.Modular` and `UnitsNet.Core` packages - publish-style packages produced as matching `6.0.0-alpha.0.<height>` packages with symbols and the expected Core dependency - Linux CI additionally runs the isolated NuGet consumer and Native AOT smoke test The local build reports two existing obsolete-quantity warnings from generated legacy UnitsNet code and no errors.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related to #372, #1180
Experiment with splitting up UnitsNet nuget into:
This is already done for UnitsNet.nanoFramework nugets:
https://www.nuget.org/packages?q=unitsnet.nanoframework
We might also provide meta nuget packages that bring in multiple nugets in a single package:
Benefits
UnitsNet.dllis ~2MB as of 2023-01-07.Problems
QuantityTypeenum must be replaced by strings and usingQuantityInfoinsteadUnitSystemandBaseUnitsrely on the 7 SI quantities Length, Mass, etc.Speed = Length / DurationandMass.FromGravitationalForce(Force f). We might be able to provide this with meta nuget packages that bring in the most common quantities and arithmetic/conversions between them.Design proposal
QuantityInfoto fully describe a quantity, instead of relying on generated code for known quantities spread over various types.UnitAbbreviationsCache.LoadGeneratedAbbreviations()based on generated code.Acceleration.RegisterDefaultConversionsand similar for other quantities.