Table of Contents

Class RequiredGuid

Namespace
FunctionalDdd
Assembly
FunctionalDdd.CommonValueObjects.dll

Base class for creating strongly-typed GUID value objects that cannot have the default (empty) GUID value. Provides a foundation for entity identifiers and other domain concepts represented by GUIDs.

public abstract class RequiredGuid : ScalarValueObject<Guid>, IComparable<ValueObject>, IEquatable<ValueObject>, IConvertible
Inheritance
RequiredGuid
Implements
Inherited Members
Extension Methods

Examples

Creating a strongly-typed entity identifier:

// Define the value object (partial keyword enables source generation)
public partial class CustomerId : RequiredGuid
{
}

// The source generator automatically creates:
// - public static CustomerId NewUnique() => new(Guid.NewGuid());
// - public static Result<CustomerId> TryCreate(Guid? value)
// - public static Result<CustomerId> TryParse(string? value)
// - private CustomerId(Guid value) : base(value) { }

// Usage examples:

// Generate a new unique ID
var customerId = CustomerId.NewUnique();

// Create from existing GUID with validation
var result1 = CustomerId.TryCreate(existingGuid);
// Returns: Success(CustomerId) if guid != Guid.Empty
// Returns: Failure(ValidationError) if guid == Guid.Empty

// Parse from string
var result2 = CustomerId.TryParse("550e8400-e29b-41d4-a716-446655440000");
// Returns: Success(CustomerId) if valid GUID format
// Returns: Failure(ValidationError) if invalid format or empty GUID

// In entity constructors
public class Customer : Entity<CustomerId>
{
    public EmailAddress Email { get; }

    private Customer(CustomerId id, EmailAddress email) : base(id)
    {
        Email = email;
    }

    public static Result<Customer> Create(EmailAddress email) =>
        email.ToResult()
            .Map(e => new Customer(CustomerId.NewUnique(), e));
}

Using in API endpoints with automatic JSON serialization:

// Request DTO
public record GetCustomerRequest(CustomerId CustomerId);

// API endpoint
app.MapGet("/customers/{id}", (string id) =>
    CustomerId.TryParse(id)
        .Bind(_customerRepository.GetAsync)
        .Map(customer => new CustomerDto(customer))
        .ToHttpResult());

// JSON request/response examples:
// Request: GET /customers/550e8400-e29b-41d4-a716-446655440000
// Response: { "customerId": "550e8400-e29b-41d4-a716-446655440000", "name": "John" }
// 
// Invalid GUID: GET /customers/00000000-0000-0000-0000-000000000000
// Response: 400 Bad Request with ValidationError

Multiple strongly-typed IDs in the same domain:

public partial class CustomerId : RequiredGuid { }
public partial class OrderId : RequiredGuid { }
public partial class ProductId : RequiredGuid { }

public class Order : Entity<OrderId>
{
    public CustomerId CustomerId { get; }
    private readonly List<OrderLine> _lines = [];

    public Result<Order> AddLine(ProductId productId, int quantity) =>
        this.ToResult()
            .Ensure(_ => quantity > 0, Error.Validation("Quantity must be positive"))
            .Tap(_ => _lines.Add(new OrderLine(productId, quantity)));

    // Compiler prevents mixing IDs:
    // AddLine(customerId, 5); // Won't compile - type safety!
}

Remarks

This class extends ScalarValueObject<T> to provide a specialized base for GUID-based value objects with automatic validation that prevents empty/default GUIDs. When used with the partial keyword, the CommonValueObjectGenerator source generator automatically creates:

  • Static factory methods (NewUnique, TryCreate, TryParse)
  • Validation logic that ensures non-empty GUIDs
  • JSON serialization support
  • Comparison and equality operations
  • String parsing and formatting

Common use cases:

  • Entity identifiers (CustomerId, OrderId, ProductId)
  • Correlation IDs for distributed tracing
  • Session or transaction identifiers
  • Any domain concept requiring a globally unique, non-empty identifier

Benefits over plain GUIDs:

  • Type safety: Cannot accidentally use CustomerId where OrderId is expected
  • Validation: Prevents empty/default GUIDs at creation time
  • Domain clarity: Makes code more self-documenting and expressive
  • Serialization: Consistent JSON and database representation
  • Factory methods: Clean API for creating new unique identifiers

Constructors

RequiredGuid(Guid)

Initializes a new instance of the RequiredGuid class with the specified GUID value.

protected RequiredGuid(Guid value)

Parameters

value Guid

The GUID value. Must not be Empty.

Remarks

This constructor is protected and should be called by derived classes. When using the source generator (with partial keyword), a private constructor is automatically generated that includes validation.

Direct instantiation should be avoided. Instead, use the generated factory methods:

  • NewUnique() - Generate a new unique GUID
  • TryCreate(Guid?) - Create from GUID with validation
  • TryParse(string?) - Parse from string with validation

See Also