namespace Before;
///
/// A tiny hand-rolled fake of EF's DbContext: it keeps a change-tracker
/// (a registration collection of the entities it knows
/// about) and a that fakes SaveChangesAsync.
///
/// This is deliberately NOT real EF Core — no providers, no SQLite, no NuGet
/// beyond xUnit. The point of the exercise is the *shape of the dependencies*
/// (domain object -> DbContext), not EF's behaviour.
///
public class DbContext
{
// The change tracker: the set of entities this context is responsible for.
// (EF calls this its change tracker; a list stands in for the
// id -> entity registration dictionary.)
private readonly List _tracked = new();
///
/// Attach an entity to this context (EF's Add). Sets the
/// active-record back-reference so the entity knows its owner.
///
public void Attach(DbBase entity)
{
ArgumentNullException.ThrowIfNull(entity);
entity.DbContext = this;
if (!_tracked.Contains(entity))
_tracked.Add(entity);
}
///
/// Fake SaveChangesAsync: walk the tracked entities and assign a
/// fresh to any whose id is still .
/// Returns the number of entities that were (re)saved — i.e. newly
/// identified — mirroring EF's "rows written" return value.
///
public int Save()
{
var saved = 0;
foreach (var entity in _tracked)
{
if (entity.Id == Guid.Empty)
{
entity.Id = Guid.NewGuid();
saved++;
}
}
return saved;
}
/// True if is in this context's tracker.
public bool IsTracked(DbBase entity) => _tracked.Contains(entity);
/// Read-only view of the entities this context currently tracks.
public IReadOnlyList Tracked => _tracked;
}