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
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 GUIDTryCreate(Guid?)- Create from GUID with validationTryParse(string?)- Parse from string with validation