Migration and upgrade guide for adopting EricksonLopez.SharedKernel in your .NET applications.
| Concept | Base Type / Interface in EricksonLopez.SharedKernel | Purpose |
|---|---|---|
| Strongly-Typed ID | IStrongId<TSelf, TValue> |
Type-safe identity wrapping primitives (Guid, long, etc.) |
| Entity Interface | IEntity<TId> |
Core generic contract exposing Id |
| Domain Entity | Entity<TId> |
Base class with type + ID equality |
| Domain Event Contract | IHasDomainEvents |
Non-generic SRP contract for atomically draining events via DrainDomainEvents() |
| Aggregate Root Marker | IAggregateRoot |
Marker interface inheriting IHasDomainEvents |
| Aggregate Root Base | AggregateRoot<TId> |
Consistency boundary with lazy event sourcing |
| Domain Event Base | DomainEvent |
Abstract record with Id (UUIDv7, type EventId) and OccurredAt (UTC) |
| Value Object Base | ValueObject |
Base record for structural multi-attribute concepts |
| Value Object Metadata | ValueObjectAttribute |
Static attribute for Native AOT and source generators |
// Before (Mutable / Inconsistent)
public abstract class LegacyEntity
{
public Guid Id { get; set; }
}
// After (Immutable Identity + Type Guard)
using EricksonLopez.SharedKernel;
public sealed class Order : AggregateRoot<OrderId>
{
public Order(OrderId id) : base(id) { }
}// Before (Plain interface without sequential identity)
public interface IDomainEvent { }
public record OrderPlacedEvent(Guid OrderId) : IDomainEvent;
// After (Inheriting DomainEvent with UUIDv7 Id and UTC OccurredAt; aliases EventId/OccurredOn available)
using EricksonLopez.SharedKernel;
public sealed record OrderPlacedEvent(OrderId OrderId) : DomainEvent;Adopting IStrongId<TSelf, TValue> can be done incrementally on an entity-by-entity basis:
// Step 1: Define Strongly Typed ID
public readonly record struct OrderId(Guid Value) : IStrongId<OrderId, Guid>;
// Step 2: Use in Aggregate Root
public sealed class Order : AggregateRoot<OrderId>
{
public Order(OrderId id) : base(id) { }
}