Functorium Framework Integration
Overview
Section titled “Overview”Covers learning and practical application of the Functorium framework’s value object type hierarchy.
Learning Objectives
Section titled “Learning Objectives”- Understand the framework type hierarchy
- How to use
SimpleValueObject<T> - How to use
ComparableSimpleValueObject<T> - Implementing composite
ValueObject
Framework Type Hierarchy
Section titled “Framework Type Hierarchy”IValueObject (interface — naming convention constants) └── AbstractValueObject (base class — equality, hash code, ORM proxy) ├── ValueObject (CreateFromValidation<TVO, TValue> helper) │ └── SimpleValueObject<T> (single value wrapper, CreateFromValidation<TVO> helper, protected T Value) └── ComparableValueObject (IComparable, comparison operators) └── ComparableSimpleValueObject<T> (single comparable value wrapper, protected T Value)How to Run
Section titled “How to Run”cd Docs/tutorials/Functional-ValueObject/04-practical-guide/01-Functorium-Framework/FunctoriumFrameworkdotnet runExpected Output
Section titled “Expected Output”=== Functorium Framework Integration ===
1. SimpleValueObject<T> Usage Example──────────────────────────────────────── Valid email: user@example.com Error: Not a valid email format.
2. ComparableSimpleValueObject<T> Usage Example──────────────────────────────────────── Before sorting: 30, 25, 35 After sorting: 25, 30, 35
3. ValueObject (composite) Usage Example──────────────────────────────────────── Address: Seoul Gangnam-gu Teheran-ro 123 (06234)
4. Framework Type Hierarchy──────────────────────────────────────── ...Core Code Explanation
Section titled “Core Code Explanation”SimpleValueObject<T>
Section titled “SimpleValueObject<T>”The
Valueproperty isprotected, so to access the value from outside, use the explicit conversion operator (explicit operator T) or define a separate public property.
public abstract class SimpleValueObject<T> : ValueObject where T : notnull{ protected T Value { get; }
protected SimpleValueObject(T value) { Value = value; }
protected override IEnumerable<object> GetEqualityComponents() { yield return Value; }
// Explicit conversion operator (access value from outside) public static explicit operator T(SimpleValueObject<T>? valueObject) => ...;
// CreateFromValidation helper public static Fin<TVO> CreateFromValidation<TVO>( Validation<Error, T> validation, Func<T, TVO> factory) where TVO : SimpleValueObject<T>;}ComparableSimpleValueObject<T>
Section titled “ComparableSimpleValueObject<T>”Inherits from
ComparableValueObjectand is in a separate hierarchy fromSimpleValueObject<T>.
public abstract class ComparableSimpleValueObject<T> : ComparableValueObject where T : notnull, IComparable{ protected T Value { get; }
protected ComparableSimpleValueObject(T value) { Value = value; }
protected override IEnumerable<IComparable> GetComparableEqualityComponents() { yield return Value; }
// Explicit conversion operator (access value from outside) public static explicit operator T(ComparableSimpleValueObject<T>? valueObject) => ...;}ValidationRules<T> System
Section titled “ValidationRules<T> System”// Validation starting point where type parameter is specified only onceValidationRules<Email>.NotNull(value) .ThenNotEmpty() .ThenNormalize(v => v.Trim().ToLowerInvariant()) .ThenMaxLength(MaxLength) // public const int MaxLength = 320; .ThenMatches(EmailRegex(), "Invalid email format");
// DomainError.For<T>() patternDomainError.For<Email>(new Empty(), value, "Email cannot be empty");DomainError.For<Password>(new TooShort(MinLength: 8), value, "Password too short");Q1: What criteria determine the choice between SimpleValueObject<T> and ComparableSimpleValueObject<T>?
Section titled “Q1: What criteria determine the choice between SimpleValueObject<T> and ComparableSimpleValueObject<T>?”A: Use ComparableSimpleValueObject<T> when size comparison or sorting of values is needed, and SimpleValueObject<T> when only equality comparison is needed. For example, Email does not need sorting so it inherits SimpleValueObject<string>, while Age needs comparison so it inherits ComparableSimpleValueObject<int>.
Q2: Why is the Value property protected?
Section titled “Q2: Why is the Value property protected?”A: Because direct access to the internal value from outside can break the encapsulation of the value object. When external access to the value is needed, use the explicit operator T conversion operator or define a separate public property appropriate to the domain.
Q3: Is the ValidationRules<T> system mandatory?
Section titled “Q3: Is the ValidationRules<T> system mandatory?”A: No. You can validate directly with if statements and the DomainError.For<T>() pattern. ValidationRules<T> is a convenience system for when you want to express common validations like NotNull, ThenNotEmpty, ThenMaxLength concisely through chaining.
Next Steps
Section titled “Next Steps”Learn ORM integration patterns.