Skip to content

Extending with Custom Units

Andreas Gullberg Larsen edited this page Jul 15, 2015 · 20 revisions

What does extending even mean?

Units.NET roughly consists of these parts:

  • Unit classes, like Length and Force
  • Unit enums, like LengthUnit and ForceUnit
  • UnitSystem for storing/looking up unit abbreviations and unit enums in various cultures, used by ToString() and Parse() in unit classes
  • JSON files for defining units, conversion functions and abbreviations
  • Powershell scripts for generating unit classes, unit enums and test code stubs

Since units are classes on their own, extending is a vague term that boils down to 3 options:

  1. Write your unit classes and tests manually.
  2. Write your unit classes and tests manually, but add your custom unit abbreviations to UnitSystem in order to reuse it for Parse() and ToString() methods.
  3. Generate your unit classes and tests by copying the powershell scripts and writing your own unit .json files. You'll have to modify the scripts to change namespace, folder structure and possibly other things that I don't recall.

Beyond this I recommend you

  • Follow the same naming conventions and general style of implementation
  • Use UnitsNet.Foo namespace, where Foo is a domain/group name for your custom units

For options 2 and 3, adding custom unit abbreviations to UnitSystem is done at runtime, with something like this:

CultureInfo cultureInfo = CultureInfo.GetCultureInfo("en-US");
UnitSystem unitSystem = UnitSystem.GetCached(cultureInfo);
unitSystem.MapUnitToAbbreviation(FooUnit.Bar, "bar");

Assert.AreEqual("bar", unitSystem.GetDefaultAbbreviation(FooUnit.Bar));
Assert.AreEqual(FooUnit.Bar, unitSystem.Parse<FooUnit>("bar");

See ToString() and Parse() in Length.cs or any other unit class for how we implement these.

Requirements

If you intend to reuse UnitSystem, you need to have a unit enum for each unit class, such as the LengthUnit enum for the Length class.

Custom Units vs Core Units

Generally we want to keep the core Units.NET library small, but at the same time cover units that are widely used in different fields of engineering. As a rule of thumb, if the unit is generally known to people outside the engineering or industry domain, then it should be included in the core library. Otherwise, consider creating an external unit or create a new issue for Units.NET to start a discussion.

Candidates for custom units:

History

In 2.0 we added support for custom units via T4 templates. In 3.0 it was modified to use powershell scripts and JSON files and to no longer use special attributes in code. This simplifies adding units by reducing the steps, it does not require Visual Studio and you can now add custom units for parsing and getting abbreviations without using the templating system.