ScaleUtilities 3.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package ScaleUtilities --version 3.0.0
                    
NuGet\Install-Package ScaleUtilities -Version 3.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ScaleUtilities" Version="3.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ScaleUtilities" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="ScaleUtilities" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ScaleUtilities --version 3.0.0
                    
#r "nuget: ScaleUtilities, 3.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ScaleUtilities@3.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ScaleUtilities&version=3.0.0
                    
Install as a Cake Addin
#tool nuget:?package=ScaleUtilities&version=3.0.0
                    
Install as a Cake Tool

ScaleUtilities

A comprehensive .NET library for unit conversions across multiple scale types including Weight, Length, Volume, Temperature, Speed, Velocity, Angle, Voltage, Illuminance, Concentration, Volumetric Flow Rate, Time, Photosynthetically Active Radiation (PPFD), Global Horizontal Irradiance, Atmospheric Pressure, and Generic/standalone units. Features formula-based conversions using NCalc, extensive unit support, and validation utilities.

I. Overview

ScaleUtilities is a powerful .NET 9 library designed for converting values between units of the same measurement type. The library provides:

  • 🔄 Universal Unit Conversion: Convert between units within the same scale type (e.g., kilograms to pounds, meters to feet)
  • 📏 Scale Types Supported: Weight, Length, Volume, Temperature, Speed, Velocity, Angle, Voltage, Illuminance, Volumetric Flow Rate, Time, Photosynthetically Active Radiation (PPFD), Global Horizontal Irradiance, Atmospheric Pressure, Generic/standalone units (e.g. percentage), Wireless Signal Strength, Electrical Conductivity, and five dimension-specific concentration types (Mass/Volume, Mass/Mass, Volume/Volume, Molar, Parts-Per). The legacy combined Concentration type remains for backwards compatibility.
  • 🧮 Formula-Based Conversions: Uses NCalc for mathematical expression evaluation, supporting complex conversion formulas
  • ✅ Validation Tools: Built-in validation utilities to ensure unit and scale type combinations are valid
  • 🎯 Type-Safe: Strongly typed with comprehensive C# models and enums
  • ⚡ High Performance: Optimized conversion trees for fast lookups and calculations
  • 🌐 Multi-Language Support: Conversion formulas available for C#, JavaScript, Python, Java, and TypeScript

Key Features

  • Extensive Unit Support: Over 100+ units across all scale types
  • International Standards: Follows SI, Imperial, US Customary, and specialized measurement systems
  • Error Handling: Comprehensive exception handling with detailed error messages
  • Async Support: Asynchronous methods for formula evaluation
  • Documentation: Full XML documentation for IntelliSense support

II. Installation

From MyGet Feed

The ScaleUtilities library is available from our MyGet feed:

# Add the MyGet feed to your NuGet sources
dotnet nuget add source https://www.myget.org/F/cms-tool/api/v3/index.json -n "CMS Tools"

# Install the package
dotnet add package ScaleUtilities --version 1.0.1 --source "CMS Tools"

Or visit the MyGet package page directly: https://www.myget.org/feed/cms-tool/package/nuget/ScaleUtilities

Package Manager Console

Install-Package ScaleUtilities -Version 1.0.1 -Source "https://www.myget.org/F/cms-tool/api/v3/index.json"

PackageReference (csproj)

<PackageReference Include="ScaleUtilities" Version="1.0.1" />

III. Supported Types and Their Units

🏋️ Weight (25 units)

Metric Units: Microgram, Milligram, Centigram, Decigram, Gram, Decagram, Hectogram, Kilogram, Metric Ton, Quintal
Imperial/US: Ounce, Pound, Stone, Short Ton, Long Ton
Troy System: Troy Ounce, Troy Pound, Pennyweight
Apothecary: Grain, Dram, Apothecary Ounce
Specialty: Carat, Atomic Mass Unit

📏 Length (8 units)

Metric: Millimeter, Centimeter, Meter, Kilometer
Imperial: Inch, Foot, Yard, Mile

🫗 Volume (9 units)

Metric: Milliliter, Liter, Cubic Meter
US Customary: Fluid Ounce, Cup, Pint, Quart, Gallon

🌡️ Temperature (5 units)

Celsius, Fahrenheit, Kelvin, Rankine, Réaumur

🏃 Speed (11 units)

Metric: Meters/Second, Kilometers/Hour, Centimeters/Second, Millimeters/Second
Imperial: Miles/Hour, Feet/Second, Inches/Second, Yards/Second
Nautical: Knots
Scientific: Speed of Light, Mach

🎯 Velocity (11 units)

Same units as Speed with directional components

📐 Angle (11 units)

Standard: Degrees, Radians, Gradians
Subdivisions: Arc Minutes, Arc Seconds
Military: Mils, NATO Mils
Fractional: Turns, Right Angles
Historical: Compass Points, Binary Degrees

⚡ Voltage (10 units)

SI Units: Nanovolts, Microvolts, Millivolts, Volts, Kilovolts, Megavolts, Gigavolts
Electrical: Statvolts, Abvolts
Scientific: Planck Voltage

💡 Illuminance (9 units)

SI: Millilux, Lux, Kilolux, Lumen/Square Meter
Imperial: Foot-candle, Lumen/Square Foot, Lumen/Square Inch
CGS: Phot, Nox

⏱️ Time (12 units)

Sub-second: Nanoseconds, Microseconds, Milliseconds
Common: Seconds (base), Minutes, Hours, Days, Weeks
Calendar (averaged): Months, Years, Decades, Centuries

Calendar units use averaged lengths (Julian year = 365.25 days, month = year / 12) because the converter is stateless and has no calendar/date context. Sub-second and common units are exact.

☀️ Photosynthetically Active Radiation (4 units)

Photon Flux Density (PPFD, SI): Moles/m²/s, Millimoles/m²/s, Micromoles/m²/s (base), Nanomoles/m²/s

PAR is measured as Photosynthetic Photon Flux Density (PPFD) in µmol·m⁻²·s⁻¹. Only SI mole-prefix units are included, so every conversion is exact and assumption-free. Radiometric (W/m²) and photometric (lux) conversions are intentionally excluded because they are non-linear and depend on the light source's spectral distribution.

🔆 Global Horizontal Irradiance (7 units)

Metric (SI): Watts/m² (base), Kilowatts/m², Milliwatts/cm², Microwatts/cm² Solar: Calories/cm²/min, Langleys/min Imperial: BTU/(h·ft²)

GHI is the total shortwave solar power on a horizontal surface, measured as irradiance (power per area) in W·m⁻². Every factor is derived from exact defined constants (1 IT calorie = 4.1868 J, 1 IT BTU = 1055.05585262 J, 1 ft² = 0.09290304 m²), so all conversions are exact. PPFD (µmol·m⁻²·s⁻¹) and lux conversions are intentionally excluded because they are spectrum-dependent and non-linear.

🌡️ Atmospheric Pressure (10 units)

Metric (SI): Pascal (base), Hectopascal, Kilopascal, Megapascal, Bar, Millibar, Atmosphere, Millimetre of Mercury (mmHg) Imperial: Inch of Mercury (inHg), Pound per Square Inch (psi)

Atmospheric (barometric) pressure is force per unit area, measured in pascals. Every factor is derived from exact defined constants (1 atm = 101325 Pa, 1 bar = 100000 Pa, 1 conventional mmHg = 133.322387415 Pa, 1 inHg = 3386.389 Pa, 1 psi = 6894.757293168 Pa), so all conversions are exact. Gauge pressures (psig, barg) and pressure↔altitude/head-of-fluid conversions are intentionally excluded because they are not pure multiplicative factors.

🏷️ Generic / Standalone Units (1 unit)

Generic: Percentage (%)

Generic units are self-contained: each unit is a conversion island with an empty conversion tree. Only the identity conversion (same unit → same unit, value unchanged) succeeds; any attempt to convert a generic unit to a different unit throws, because generic units have no conversions. This is the right home for dimensionless quantities such as a bare percentage that shouldn't be converted to anything else.

🧪 Concentration

Concentration is split into dimension-specific scale types so that every conversion within a type is exact and requires no assumed density or molar mass. Units in different types are not mutually convertible, because bridging (e.g.) mass/mass to mass/volume would require a density the library deliberately refuses to assume.

  • Mass/Volume Concentration (MassVolumeConcentration, pivot g/L): Kilograms/Cubic Meter, Grams/Liter, Milligrams/Liter, Micrograms/Liter, Grams/Cubic Meter, Milligrams/Cubic Meter, Pounds/Gallon, Ounces/Gallon, Grains/Gallon, Pounds/Cubic Foot, Percent Weight by Volume (% w/v)
  • Mass/Mass Concentration (MassMassConcentration, pivot g/g): Grams/Gram, Milligrams/Gram, Micrograms/Gram, Nanograms/Gram, Grams/Kilogram, Milligrams/Kilogram (mg/kg), Micrograms/Kilogram, Nanograms/Kilogram, Percent by Weight (% w/w)
  • Volume/Volume Concentration (VolumeVolumeConcentration, pivot L/L): Percent by Volume (% v/v), Per Mille by Volume (‰ v/v), Milliliters/Liter, Microliters/Liter, Liters/Cubic Meter, Milliliters/Cubic Meter
  • Molar Concentration (MolarConcentration, pivot mol/L): Molar, Millimolar, Micromolar, Nanomolar
  • Parts-Per Concentration (PartsPerConcentration, dimensionless): Parts per Million, Parts per Billion, Parts per Trillion

Deprecated: the original single Concentration type still exists for backwards compatibility. It interconverts all of the above via an assumed density (1 g/mL) and molar mass (1 g/mol). Prefer the dimension-specific types above for new code.

💧 Volumetric Flow Rate (15 units)

Metric - Milliliter: Milliliter/Second, Milliliter/Minute, Milliliter/Hour
Metric - Liter: Liter/Second, Liter/Minute, Liter/Hour
Metric - Cubic Meter: Cubic Meter/Second, Cubic Meter/Minute, Cubic Meter/Hour
US Customary - Fluid Ounce: Fluid Ounce/Second, Fluid Ounce/Minute, Fluid Ounce/Hour
US Customary - Gallon: Gallon/Second, Gallon/Minute (GPM), Gallon/Hour

Common Applications: HVAC systems, plumbing, irrigation, industrial pipelines, medical IV drips, fuel injection systems, water pumps, fire sprinkler systems

IV. Utility Methods

ScaleUnitValidationUtilities

Located in ScaleUtilities.Utilities namespace

Methods

Validate(ScaleUnit scaleUnit)

  • Parameters: ScaleUnit scaleUnit - The ScaleUnit object to validate
  • Return Type: void
  • Exceptions:
    • ArgumentNullException - When scaleUnit is null
    • InvalidScaleUnitException - When the ScaleUnit has invalid type/code combination
  • Description: Validates a ScaleUnit and throws an exception if invalid

IsValid(ScaleUnit scaleUnit)

  • Parameters: ScaleUnit scaleUnit - The ScaleUnit object to check
  • Return Type: bool
  • Description: Returns true if the ScaleUnit has a valid type and code combination

IsValid(ScaleTypes type, string code)

  • Parameters:
    • ScaleTypes type - The scale type enum
    • string code - The unit code to validate
  • Return Type: bool
  • Description: Returns true if the scale type and unit code combination is valid

Conversion Tree Utilities

Each scale type has its own conversion utility class:

WeightConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters:
    • decimal value - Value to convert
    • string sourceUnit - Source unit code (e.g., "KILOGRAM")
    • string targetUnit - Target unit code (e.g., "POUND")
  • Return Type: decimal
  • Description: Converts weight values between different units
LengthConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts length values between different units
VolumeConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts volume values between different units
TemperatureConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts temperature values between different units (handles offset-based conversions)
SpeedConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts speed values between different units
VelocityConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts velocity values between different units
AngleConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts angle values between different units
VoltageConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts voltage values between different units
IlluminanceConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts illuminance values between different units
ConcentrationConversionTreeUtilities (deprecated)

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts concentration values between different units using assumed density/molar mass. Kept for backwards compatibility — prefer the dimension-specific utilities below.
MassVolumeConcentrationConversionTreeUtilities / MassMassConcentrationConversionTreeUtilities / VolumeVolumeConcentrationConversionTreeUtilities / MolarConcentrationConversionTreeUtilities / PartsPerConcentrationConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts concentration values within a single physical dimension. Conversions stay within the group and require no assumed density or molar mass; cross-group conversions throw.
VolumetricFlowRateConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts volumetric flow rate values between different units (e.g., liters per second to gallons per minute)
PhotosyntheticallyActiveRadiationConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts Photosynthetically Active Radiation (PPFD) values between SI photon-flux-density units (e.g., micromoles per square metre per second to moles per square metre per second)
GlobalHorizontalIrradianceConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts Global Horizontal Irradiance (solar irradiance) values between power-per-area units (e.g., watts per square metre to kilowatts per square metre, langleys per minute, or BTU per hour per square foot)
AtmosphericPressureConversionTreeUtilities

Convert(decimal value, string sourceUnit, string targetUnit)

  • Parameters: Same as WeightConversionTreeUtilities
  • Return Type: decimal
  • Description: Converts atmospheric (barometric) pressure values between force-per-area units (e.g., pascals to bar, atmospheres, millimetres of mercury, inches of mercury, or pounds per square inch)

Unit Code Constants

Each scale type provides constants for unit codes:

  • WeightUnitCodes - All weight unit codes and validation methods
  • LengthUnitCodes - All length unit codes
  • VolumeUnitCodes - All volume unit codes
  • TemperatureUnitCodes - All temperature unit codes and validation methods
  • SpeedUnitCodes - All speed unit codes and validation methods
  • VelocityUnitCodes - All velocity unit codes and validation methods
  • AngleUnitCodes - All angle unit codes and validation methods
  • VoltageUnitCodes - All voltage unit codes and validation methods
  • IlluminanceUnitCodes - All illuminance unit codes and validation methods
  • ConcentrationUnitCodes - All concentration unit codes and validation methods
  • VolumetricFlowRateUnitCodes - All volumetric flow rate unit codes and symbol retrieval methods

Usage Examples

Basic Unit Conversion

using ScaleUtilities.Utilities;
using ScaleUtilities.Constants;

// Convert 1 kilogram to pounds
decimal result = WeightConversionTreeUtilities.Convert(1m, WeightUnitCodes.Kilogram, WeightUnitCodes.Pound);
// Result: 2.20462262184878

// Convert 100 degrees Celsius to Fahrenheit
decimal tempResult = TemperatureConversionTreeUtilities.Convert(100m, TemperatureUnitCodes.Celsius, TemperatureUnitCodes.Fahrenheit);
// Result: 212

// Convert 15.85 gallons per minute to liters per second
decimal flowResult = VolumetricFlowRateConversionTreeUtilities.Convert(15.85m, VolumetricFlowRateUnitCodes.GallonPerMinute, VolumetricFlowRateUnitCodes.LiterPerSecond);
// Result: 1.0 (approximately)

Unit Validation

using ScaleUtilities.Utilities;
using ScaleUtilities.Models;
using ScaleUtilities.Constants;

// Create a weight unit
var weightUnit = new WeightUnit(WeightUnitCodes.Kilogram);

// Validate the unit
bool isValid = ScaleUnitValidationUtilities.IsValid(weightUnit);
// Result: true

// Validate type/code combination
bool isValidCombo = ScaleUnitValidationUtilities.IsValid(ScaleTypes.Weight, WeightUnitCodes.Kilogram);
// Result: true

// Validate with exception throwing
try 
{
    ScaleUnitValidationUtilities.Validate(weightUnit);
    Console.WriteLine("Unit is valid!");
}
catch (InvalidScaleUnitException ex)
{
    Console.WriteLine($"Invalid unit: {ex.Message}");
}

Working with Unit Codes

using ScaleUtilities.Constants;

// Check if a unit code is valid
bool isValidWeight = WeightUnitCodes.IsValidWeightUnit("KILOGRAM");
// Result: true

// Get unit system category
string system = WeightUnitCodes.GetUnitSystem("KILOGRAM");
// Result: "Metric"

// Get all available units
string[] allWeightUnits = WeightUnitCodes.AllUnits;
// Result: Array of all weight unit codes

Volumetric Flow Rate Conversions

using ScaleUtilities.Utilities;
using ScaleUtilities.Constants;

// Convert water pump flow rate from liters per second to GPM
decimal pumpFlow = 5m; // 5 L/s
decimal gpm = VolumetricFlowRateConversionTreeUtilities.Convert(
    pumpFlow, 
    VolumetricFlowRateUnitCodes.LiterPerSecond, 
    VolumetricFlowRateUnitCodes.GallonPerMinute);
// Result: 79.25 GPM (approximately)

// Convert medical IV drip rate
decimal ivRate = 125m; // 125 mL/h
decimal mlPerMin = VolumetricFlowRateConversionTreeUtilities.Convert(
    ivRate,
    VolumetricFlowRateUnitCodes.MilliliterPerHour,
    VolumetricFlowRateUnitCodes.MilliliterPerMinute);
// Result: 2.083 mL/min (approximately)

// Get all available volumetric flow rate units
var availableUnits = VolumetricFlowRateConversionTreeUtilities.GetAvailableUnits();
// Returns array of VolumetricFlowRateUnit instances

// Get unit symbol
string symbol = VolumetricFlowRateUnitCodes.GetSymbol(VolumetricFlowRateUnitCodes.GallonPerMinute);
// Result: "gal/min"

Requirements

  • .NET 9.0 or higher
  • NCalc.NetCore 1.0.1 (automatically installed)

License

This library is licensed under the MIT License.

Support

For issues, questions, or contributions, please visit our GitLab repository: https://gitlab.com/iot93/back-end/commons/uom


© 2024 Linh Nguyen. All rights reserved.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on ScaleUtilities:

Package Downloads
IotVn.Measurements.Cores

Package Description

AssetService.Cores

Package Description

ApiFeatures.Uom.Apis

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.1 54 11/4/2026
3.0.0 62 11/3/2026
2.0.4 826 5/7/2026
1.0.0 345 9/27/2025

Version 2.1.0: New Scale Dimensions, Density-Free Concentration Split, and Generic Units

This is a backwards-compatible (additive) release: all new scale types are appended to the ScaleTypes
enum, so existing enum ordinals and the pre-existing public API are unchanged.

⚠️ DEPRECATIONS:
- **ScaleTypes.Concentration is now deprecated** (still functional for backwards compatibility)
 * The legacy mixed-dimension concentration pool interconverts mass/volume, mass/mass, volume/volume, molar and parts-per units by ASSUMING density (1 g/mL) and molar mass (1 g/mol), which is physically incorrect for real substances.
 * Migrate to the new dimension-specific concentration types below, each of which is density-free and exact within its group.

✨ NEW SCALE TYPES:
- **Concentration split into 5 dimension-specific, density-free types:**
 * MassVolumeConcentration — g/L, mg/L, lb/gal, % w/v, etc.
 * MassMassConcentration — g/g, mg/kg, ng/g, % w/w (dimensionless mass ratios)
 * VolumeVolumeConcentration — % v/v, mL/L, µL/L, L/m³ (dimensionless volume ratios)
 * MolarConcentration — M, mM, µM, nM (density- and molar-mass-free)
 * PartsPerConcentration — ppm, ppb, ppt (pure ratios)
- **Time** — s, min, h, d, wk, mo, yr. Single-pivot linear conversion on seconds; calendar units (month/year) use averaged lengths.
- **PhotosyntheticallyActiveRadiation (PPFD)** — Photon Flux Density in mol/mmol/µmol/nmol per m² per s. Single-pivot linear conversion on µmol·m⁻²·s⁻¹; only SI mole-prefix units are included so every conversion is exact. W/m² and lux are excluded (spectrum-dependent, non-linear).
- **GlobalHorizontalIrradiance (GHI)** — total shortwave solar power on a horizontal surface in W/m², kW/m², mW/cm², µW/cm², cal/cm²/min (langley/min) and BTU/(h·ft²). Single-pivot linear conversion on W·m⁻² using exact defined constants. PPFD and lux excluded (spectrum-dependent, non-linear).
- **AtmosphericPressure** — barometric pressure in Pa, hPa, kPa, MPa, bar, mbar, atm, mmHg, inHg and psi. Single-pivot linear conversion on pascals using exact defined constants. Gauge pressures (psig, barg) and pressure↔altitude/head-of-fluid conversions excluded (not pure multiplicative factors).
- **Generic** — standalone/dimensionless units (e.g. percentage, %) that cannot be converted to any other unit. Each unit is a conversion island with an empty conversion tree; only the identity conversion (same unit → same unit, value unchanged) succeeds, and any cross-unit conversion throws.

🔧 IMPROVEMENTS:
- New *ConversionTreeUtilities classes for each of the 9 new scale types, wired into ConversionUtilities (GetAllConversionTrees, GetConversionTreesForType, GetConversionTreeForUnit, Convert).
- ScaleUnitValidationUtilities.IsValid() extended to cover all 9 new scale types.
- New strongly-typed unit models (MassVolumeConcentrationUnit, TimeUnit, AtmosphericPressureUnit, etc.) and *UnitCodes constant classes with symbols and validation helpers.
- Comprehensive test coverage added for all new dimensions, including concentration-group isolation tests and JavaScript expression tests.

📖 MIGRATION GUIDE - Upgrading from 2.0.x to 2.1.0:

The legacy Concentration type still works, but should be replaced with the dimension that matches your data:

**Before (2.x):**
```csharp
// Mixed pool — assumed density/molar mass, could silently misconvert
var result = ConcentrationConversionTreeUtilities.Convert(value, "GRAMS_PER_LITER", "MOLAR");
```

**After (3.0):**
```csharp
// Pick the dimension that matches your quantity — no assumed density/molar mass
var mv = MassVolumeConcentrationConversionTreeUtilities.Convert(value, "GRAMS_PER_LITER", "MILLIGRAMS_PER_LITER");
var molar = MolarConcentrationConversionTreeUtilities.Convert(value, "MOLAR", "MILLIMOLAR");
```

**Note:** Existing ScaleTypes enum members keep their original ordinal values; the new members are appended, so numeric enum values for pre-3.0 types are unchanged.

---

Version 2.0.2: Validation Support for Electrical Conductivity and Wireless Signal Strength

✨ NEW FEATURES:
- **Enhanced ScaleUnitValidationUtilities**: Added comprehensive validation support for two additional scale types
 * ElectricalConductivity: Validates all electrical conductivity units (S/m, mS/cm, µS/cm, mho/cm, Ω⁻¹·m⁻¹, etc.)
 * WirelessSignalStrength: Validates all wireless signal strength units (dBm, dBW, dBµW, RSSI, W, %, etc.)
- **Type-Safe Validation**: ScaleUnitValidationUtilities.IsValid() now supports all 12 scale types
- **Comprehensive Test Coverage**: Added extensive unit tests for both new validation types
 * Tests for valid and invalid unit codes
 * Tests for type/code mismatch scenarios
 * Tests for null and empty code handling

🔧 IMPROVEMENTS:
- Complete validation coverage across all scale types in the library
- Better error handling with InvalidScaleUnitException for invalid units
- Improved API consistency for validation methods

📖 USAGE EXAMPLES:

**Electrical Conductivity Validation:**
```csharp
// Using IsValid with ScaleUnit object
var ecUnit = new ElectricalConductivityUnit(ScaleTypes.ElectricalConductivity, "SIEMENS_PER_METER");
bool isValid = ScaleUnitValidationUtilities.IsValid(ecUnit); // Returns true

// Using IsValid with type and code
bool isValid = ScaleUnitValidationUtilities.IsValid(
   ScaleTypes.ElectricalConductivity,
   ElectricalConductivityUnitCodes.MillisiemensPerCentimeter
); // Returns true

// Using Validate (throws exception if invalid)
ScaleUnitValidationUtilities.Validate(ecUnit); // Does not throw
```

**Wireless Signal Strength Validation:**
```csharp
// Using IsValid with ScaleUnit object
var wirelessUnit = new WirelessSignalStrengthUnit(ScaleTypes.WirelessSignalStrength, "DBM");
bool isValid = ScaleUnitValidationUtilities.IsValid(wirelessUnit); // Returns true

// Using IsValid with type and code
bool isValid = ScaleUnitValidationUtilities.IsValid(
   ScaleTypes.WirelessSignalStrength,
   WirelessSignalStrengthUnitCodes.RSSI
); // Returns true

// Using Validate (throws exception if invalid)
ScaleUnitValidationUtilities.Validate(wirelessUnit); // Does not throw
```

**Error Handling:**
```csharp
var invalidUnit = new ElectricalConductivityUnit(ScaleTypes.ElectricalConductivity, "INVALID_CODE");
try
{
   ScaleUnitValidationUtilities.Validate(invalidUnit);
}
catch (InvalidScaleUnitException ex)
{
   Console.WriteLine($"Invalid unit: {ex.Type} - {ex.Code}");
   // Output: "Invalid unit: ElectricalConductivity - INVALID_CODE"
}
```

---

Version 2.0.1: GenericScaleUnit for JSON Serialization/Deserialization

✨ NEW FEATURES:
- **GenericScaleUnit Class**: Introduced new GenericScaleUnit class for improved JSON serialization and deserialization
 * Enables dynamic unit type handling in JSON scenarios
 * Supports all scale types (Weight, Length, Volume, Temperature, Speed, Velocity, Angle, Voltage, Illuminance, Concentration, WirelessSignalStrength, ElectricalConductivity)
 * Seamless integration with existing ScaleUnit hierarchy
 * Ideal for API responses and data transfer objects requiring flexible unit representation

🔧 IMPROVEMENTS:
- Enhanced JSON compatibility across the library
- Better support for dynamic unit type scenarios

---

Version 2.0.0: MAJOR RELEASE - Breaking Changes and Symbol Display Enhancements
   
⚠️ BREAKING CHANGES - MAJOR VERSION UPDATE:
- **API Method Renamed**: GetAvailableUnits() → GetAvailableUnitCodes() in all *ConversionTreeUtilities classes
 * Old method name is no longer available
 * GetAvailableUnitCodes() returns string[] (unit codes only)
 * New GetAvailableUnits() returns strongly-typed ScaleUnit arrays with metadata
- **Return Type Changed**: GetAvailableUnits() now returns ScaleUnit-derived types instead of string[]
 * Migration required for existing code using GetAvailableUnits()
 * See Migration Guide below for step-by-step instructions

✨ NEW FEATURES:
- **Rich Unit Objects**: New GetAvailableUnits() method returns strongly-typed unit classes:
 * WeightUnit[], LengthUnit[], VolumeUnit[], TemperatureUnit[]
 * SpeedUnit[], VelocityUnit[], AngleUnit[], VoltageUnit[]
 * IlluminanceUnit[], ConcentrationUnit[], WirelessSignalStrengthUnit[], ElectricalConductivityUnit[]
- **Enhanced Metadata**: Each unit object includes Type, Code, and Symbol properties
- **Symbol Support**: Added ScaleUnitDto.Symbol property for API responses with proper Unicode encoding
- **ConversionTree.Code Property**: Added missing Code property for better API consistency

🐛 BUG FIXES - Unicode Symbol Display:
- Fixed all Unicode character encoding issues across the library:
 * µ (micro): Microgram, Microvolt, Microwatt, Microsiemens, etc.
 * ℥ (apothecary ounce): Weight units
 * ℧ (mho): Electrical conductivity units
 * Ω (omega/ohm): Electrical conductivity units
 * ° (degree): Angle units
 * π (pi): Angle units (radians)
 * ∟ (right angle): Angle units (was showing as ?)
 * ² (superscript 2): Square units (m², ft², in²)
 * ³ (superscript 3): Cubic units (m³, ft³, in³)
- Fixed missing symbols in IlluminanceUnitCodes: mlx, klx, lm/m², lm/ft², lm/in²
- Fixed missing symbols in VelocityUnitCodes: cm/s, mm/s, in/s, yd/s, c, M
- Fixed typo: Footcandle → FootCandle in IlluminanceUnitCodes
- All source files re-saved with UTF-8 BOM encoding

🔧 IMPROVEMENTS:
- Enhanced web application UTF-8 encoding in Program.cs and _Layout.cshtml
- Added JavaScriptEncoder.UnsafeRelaxedJsonEscaping for proper JSON serialization
- Comprehensive XML documentation for all GetSymbol() methods
- Improved IntelliSense support with rich unit metadata
- Better type safety throughout the library
- Consistent API patterns across all conversion utilities

📖 MIGRATION GUIDE - Upgrading from 1.x to 2.0:

**Before (1.x):**
```csharp
string[] units = WeightConversionTreeUtilities.GetAvailableUnits();
// Returns: ["KILOGRAM", "GRAM", "POUND", ...]
```

**After (2.0):**
```csharp
// Option 1: Get unit codes (same as before)
string[] unitCodes = WeightConversionTreeUtilities.GetAvailableUnitCodes();
// Returns: ["KILOGRAM", "GRAM", "POUND", ...]

// Option 2: Get rich unit objects (NEW!)
WeightUnit[] units = WeightConversionTreeUtilities.GetAvailableUnits();
// Each unit has: Type (ScaleTypes.Weight), Code ("KILOGRAM"), Symbol ("kg")

// Access unit properties:
foreach (var unit in units)
{
   Console.WriteLine($"{unit.Code}: {unit.Symbol} ({unit.Type})");
}
```

**Quick Migration Steps:**
1. Find all calls to `GetAvailableUnits()` in your code
2. If you only need unit codes (strings), rename to `GetAvailableUnitCodes()`
3. If you want unit metadata, keep `GetAvailableUnits()` and update variable types
4. Recompile and test your application

**Web Application Note:**
- Restart your application after updating
- Clear browser cache (Ctrl+Shift+Delete) for proper symbol display
- Unicode symbols (µ, ℥, ℧, Ω, °, ², ³, ∟) now display correctly

For detailed upgrade assistance, visit: https://gitlab.com/iot93/back-end/commons/uom