Skip to content

ktsu-dev/Semantics

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

ktsu.Semantics

NuGet Version NuGet Downloads Build Status

A comprehensive .NET library for creating type-safe, validated types with semantic meaning. Transform primitive string and numeric obsession into strongly-typed, self-validating domain models with comprehensive validation, specialized path handling, and a complete physics quantities system covering 80+ quantities across 8 major scientific domains with dimensional analysis and centralized physical constants.

Overview

The Semantics library enables you to create strongly-typed wrappers that carry semantic meaning and built-in validation. Instead of passing raw primitives around your application, you can create specific types like EmailAddress, FilePath, Temperature, or UserId that are impossible to misuse and automatically validate their content.

๐ŸŒŸ Key Features

  • Type Safety: Eliminate primitive obsession with strongly-typed wrappers
  • Comprehensive Validation: 50+ built-in validation attributes for all common scenarios
  • Path Handling: Specialized path types with polymorphic interfaces and file system operations
  • Complete Physics System: 80+ physics quantities across 8 scientific domains with dimensional analysis
  • Physical Constants: Centralized, type-safe access to fundamental and derived constants with validation
  • Bootstrap Architecture: Clean circular dependency resolution for complex type systems
  • Unit Conversions: Automatic unit handling with compile-time dimensional safety
  • Factory Pattern: Clean object creation with dependency injection support
  • Performance Optimized: Span-based operations, pooled builders, and minimal allocations
  • Enterprise Ready: Full .NET ecosystem integration (ASP.NET Core, Entity Framework, etc.)
  • Comprehensive Testing: Derived constants validation and physics relationship verification

๐Ÿš€ Quick Start

Installation

dotnet add package ktsu.Semantics

Basic Usage

using ktsu.Semantics;

// Define strongly-typed domain models
[IsEmail]
public sealed record EmailAddress : SemanticString<EmailAddress> { }

[HasLength(8, 50), IsNotEmpty]
public sealed record UserId : SemanticString<UserId> { }

// Simple direct usage - Clean API with type inference:

// 1. Create methods (recommended) - no generic parameters needed!
var email1 = EmailAddress.Create("user@example.com");
var userId1 = UserId.Create("USER_12345");

// 2. From character arrays
char[] emailChars = ['u', 's', 'e', 'r', '@', 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'];
var email2 = EmailAddress.Create(emailChars);

// 3. From ReadOnlySpan<char> (performance optimized)
var userId2 = UserId.Create("USER_12345".AsSpan());

// 4. Explicit string casting
var email3 = (EmailAddress)"user@example.com";
var userId3 = (UserId)"USER_12345";

// 5. Safe creation with TryCreate (no exceptions)
if (EmailAddress.TryCreate("maybe@invalid", out EmailAddress? safeEmail))
{
    // Use safeEmail - validation succeeded
}

// Compile-time safety prevents mistakes
public void SendWelcomeEmail(EmailAddress to, UserId userId) { /* ... */ }

// This won't compile - type safety in action!
// SendWelcomeEmail(userId, email); // โŒ Compiler error!

Factory Pattern Usage

// Use factory pattern (recommended for dependency injection)
var emailFactory = new SemanticStringFactory<EmailAddress>();
var userFactory = new SemanticStringFactory<UserId>();

// Clean overloaded API - Create methods
var email = emailFactory.Create("user@example.com");
var userId = userFactory.Create("USER_12345");

// All input types supported via overloading
var email2 = emailFactory.Create(['u', 's', 'e', 'r', '@', 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm']);
var userId2 = userFactory.Create("USER_12345".AsSpan());

// Safe creation with TryCreate
if (emailFactory.TryCreate("maybe@invalid", out EmailAddress? safeEmail))
{
    // Success!
}

// Legacy FromString methods still available  
var email3 = emailFactory.FromString("user@example.com");

Physics Quantities System

// Complete physics system with 80+ quantities across 8 domains
public sealed record Temperature<T> : PhysicalQuantity<Temperature<T>, T> where T : struct, INumber<T> { }
public sealed record Force<T> : PhysicalQuantity<Force<T>, T> where T : struct, INumber<T> { }
public sealed record Energy<T> : PhysicalQuantity<Energy<T>, T> where T : struct, INumber<T> { }

// Create quantities with dimensional safety
var temp = Temperature<double>.FromCelsius(25.0);      // 298.15 K
var force = Force<double>.FromNewtons(100.0);         // 100 N
var distance = Length<double>.FromMeters(5.0);        // 5 m

// Physics relationships with compile-time safety
var work = force * distance;                          // Results in Energy<double>
var power = work / Time<double>.FromSeconds(10.0);    // Results in Power<double>

// Type-safe unit conversions
Console.WriteLine(temp.ToFahrenheit());               // 77ยฐF
Console.WriteLine(force.ToPounds());                  // 22.48 lbf

// Access physical constants with type safety
var gasConstant = PhysicalConstants.Generic.GasConstant<double>();       // 8.314 J/(molยทK)
var speedOfLight = PhysicalConstants.Generic.SpeedOfLight<float>();      // 299,792,458 m/s
var planckConstant = PhysicalConstants.Generic.PlanckConstant<decimal>(); // Type-safe constant access

// Dimensional analysis prevents errors
// var invalid = force + temp;                        // โŒ Compiler error!

Path Handling

// Use specialized path types
var fileFactory = new SemanticStringFactory<AbsoluteFilePath>();
var configFile = fileFactory.Create(@"C:\app\config.json");

// Rich path operations
Console.WriteLine(configFile.FileName);        // config.json
Console.WriteLine(configFile.FileExtension);   // .json  
Console.WriteLine(configFile.DirectoryPath);   // C:\app
Console.WriteLine(configFile.Exists);          // True/False

// Polymorphic path collections
List<IPath> allPaths = [
    AbsoluteFilePath.FromString<AbsoluteFilePath>(@"C:\data.txt"),
    RelativeDirectoryPath.FromString<RelativeDirectoryPath>(@"logs\app"),
    FilePath.FromString<FilePath>(@"document.pdf")
];

// Filter by interface type
var filePaths = allPaths.OfType<IFilePath>().ToList();
var absolutePaths = allPaths.OfType<IAbsolutePath>().ToList();

Complex Validation

// Combine multiple validation rules
[IsNotEmpty, IsEmail, HasLength(5, 100)]
public sealed record BusinessEmail : SemanticString<BusinessEmail> { }

// Use validation strategies for flexible requirements
[ValidateAny] // Either email OR phone is acceptable
[IsEmail, RegexMatch(@"^\+?\d{10,15}$")]
public sealed record ContactInfo : SemanticString<ContactInfo> { }

// First-class type validation
[IsDateTime]
public sealed record ScheduledDate : SemanticString<ScheduledDate> { }

[IsDecimal, IsPositive]
public sealed record Price : SemanticString<Price> { }

[IsGuid]
public sealed record TransactionId : SemanticString<TransactionId> { }

๐Ÿ”ง Common Use Cases

E-commerce Domain

[HasLength(3, 20), IsNotEmpty]
public sealed record ProductSku : SemanticString<ProductSku> { }

[IsPositive, IsDecimal]  
public sealed record Price : SemanticString<Price> { }

[IsEmail]
public sealed record CustomerEmail : SemanticString<CustomerEmail> { }

public class Order
{
    public CustomerEmail CustomerEmail { get; set; }
    public ProductSku[] Items { get; set; }
    public Price TotalAmount { get; set; }
}

Configuration Management

[IsAbsolutePath, DoesExist]
public sealed record ConfigFilePath : SemanticString<ConfigFilePath> { }

[IsIpAddress]
public sealed record ServerAddress : SemanticString<ServerAddress> { }

[IsInRange(1, 65535)]
public sealed record Port : SemanticQuantity<Port, int> { }

Physical Constants System

All physical constants are centralized in PhysicalConstants with type-safe generic access:

// Fundamental constants (SI 2019 definitions)
var c = PhysicalConstants.Generic.SpeedOfLight<double>();        // 299,792,458 m/s
var h = PhysicalConstants.Generic.PlanckConstant<double>();      // 6.62607015ร—10โปยณโด Jโ‹…s
var k = PhysicalConstants.Generic.BoltzmannConstant<double>();   // 1.380649ร—10โปยฒยณ J/K
var NA = PhysicalConstants.Generic.AvogadroNumber<double>();     // 6.02214076ร—10ยฒยณ /mol

// Temperature constants
var T0 = PhysicalConstants.Generic.StandardTemperature<double>(); // 273.15 K
var P0 = PhysicalConstants.Generic.StandardAtmosphericPressure<double>(); // 101,325 Pa

// Conversion factors with derived validation
var ftToM = PhysicalConstants.Generic.FeetToMeters<double>();    // 0.3048 m/ft
var sqFtToSqM = PhysicalConstants.Generic.SquareFeetToSquareMeters<double>(); // Derived: ftToMยฒ

// All constants have comprehensive test coverage ensuring derived values match calculations

Complete Physics Domains

The library includes 80+ physics quantities across 8 scientific domains:

๐Ÿ”ง Mechanics (15 quantities)

// Kinematics and dynamics
var velocity = Velocity<double>.FromMetersPerSecond(15.0);
var acceleration = Acceleration<double>.FromMetersPerSecondSquared(9.8);
var force = Mass<double>.FromKilograms(10.0) * acceleration;    // F = ma

// Work and energy
var work = force * Length<double>.FromMeters(5.0);             // W = Fโ‹…d
var power = work / Time<double>.FromSeconds(2.0);              // P = W/t

โšก Electrical (11 quantities)

// Ohm's law relationships
var voltage = Voltage<double>.FromVolts(12.0);
var current = Current<double>.FromAmperes(2.0);
var resistance = voltage / current;                            // R = V/I
var power = voltage * current;                                 // P = VI

๐ŸŒก๏ธ Thermal (10 quantities)

// Thermodynamics
var temp = Temperature<double>.FromCelsius(25.0);
var heat = Heat<double>.FromJoules(1000.0);
var capacity = HeatCapacity<double>.FromJoulesPerKelvin(100.0);
var entropy = heat / temp;                                     // S = Q/T

๐Ÿงช Chemical (10 quantities)

// Chemical calculations
var moles = AmountOfSubstance<double>.FromMoles(0.5);
var molarity = moles / Volume<double>.FromLiters(2.0);         // M = n/V
var rate = ReactionRate<double>.FromMolarPerSecond(0.01);

๐Ÿ”Š Acoustic (20 quantities)

// Sound and vibration
var frequency = Frequency<double>.FromHertz(440.0);            // A4 note
var wavelength = SoundSpeed<double>.Default / frequency;       // ฮป = v/f  
var intensity = SoundIntensity<double>.FromWattsPerSquareMeter(1e-6);

โ˜ข๏ธ Nuclear (5 quantities)

// Nuclear physics
var activity = RadioactiveActivity<double>.FromBecquerels(1000.0);
var dose = AbsorbedDose<double>.FromGrays(0.001);
var exposure = Exposure<double>.FromCoulombsPerKilogram(1e-6);

๐Ÿ’ก Optical (6 quantities)

// Photometry and optics
var flux = LuminousFlux<double>.FromLumens(800.0);
var illuminance = flux / Area<double>.FromSquareMeters(4.0);   // E = ฮฆ/A
var luminance = Luminance<double>.FromCandelasPerSquareMeter(100.0);

๐ŸŒŠ Fluid Dynamics (5 quantities)

// Fluid mechanics
var viscosity = DynamicViscosity<double>.FromPascalSeconds(0.001);
var flowRate = VolumetricFlowRate<double>.FromCubicMetersPerSecond(0.1);
var reynolds = ReynoldsNumber<double>.Calculate(velocity, Length<double>.FromMeters(0.1), viscosity);

๐Ÿ›๏ธ Architecture & Design

Bootstrap Architecture

The library uses a sophisticated bootstrap architecture to resolve circular dependencies:

// BootstrapUnits class provides initial unit definitions during system initialization
// PhysicalDimensions uses BootstrapUnits to define dimensions without circular dependencies
// Units class replaces bootstrap units with full unit definitions after initialization

// This clean separation enables complex type systems while maintaining performance

Derived Constants Validation

All derived physical constants are validated against their fundamental relationships:

// Example: Area conversions are validated to ensure SquareFeetToSquareMeters = FeetToMetersยฒ
[TestMethod]
public void DerivedConstants_AreaConversions_MatchCalculatedValues()
{
    var feetToMeters = PhysicalConstants.Conversion.FeetToMeters;
    var calculatedSquareFeet = feetToMeters * feetToMeters;
    var storedSquareFeet = PhysicalConstants.Conversion.SquareFeetToSquareMeters;
    
    Assert.AreEqual(calculatedSquareFeet, storedSquareFeet, tolerance);
}
// Comprehensive test coverage ensures physical relationships are mathematically correct

๐Ÿ—๏ธ Dependency Injection

// Register factories in your DI container
services.AddTransient<ISemanticStringFactory<EmailAddress>, SemanticStringFactory<EmailAddress>>();

// Use in services
public class UserService
{
    private readonly ISemanticStringFactory<EmailAddress> _emailFactory;

    public UserService(ISemanticStringFactory<EmailAddress> emailFactory)
    {
        _emailFactory = emailFactory;
    }

    public async Task<User> CreateUserAsync(string email)
    {
        // Factory handles validation and throws meaningful exceptions
        var validatedEmail = _emailFactory.Create(email);
        return new User(validatedEmail);
    }
}

๐Ÿ“– Documentation

Comprehensive documentation is available in the docs/ directory:

๐Ÿ’ก Examples

Extensive examples are available in docs/examples/:

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE.md file for details.

๐Ÿ†˜ Support


Transform your primitive-obsessed code into a strongly-typed, self-validating domain model with ktsu.Semantics.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors 4

  •  
  •  
  •  
  •