Project · Architecture

Capacity port contract lab

Run six independent local boundary checks. Files share one console assembly; separate physical dependency enforcement is demonstrated by the external lesson solutions.

All C# source files below are loaded together in the playground. Files written by a run live in its virtual directory.

Program.cs

var checks = CapacityChecks.Run();
foreach (var check in checks) Console.WriteLine($"{check.Name}:{(check.Passed ? "PASS" : "FAIL")}");
Console.WriteLine($"passed:{checks.Count(check => check.Passed)}/{checks.Count}");
return checks.All(check => check.Passed) ? 0 : 1;

Domain/CapacityRule.cs

public static class CapacityRule { public static bool CanTake(int units, int free) => units > 0 && units <= free; }

Application/Reserve.cs

public interface ICapacity { int Free { get; } void Commit(int units); }
public sealed class Reserve
{
    private readonly ICapacity capacity;
    public Reserve(ICapacity capacity) { this.capacity = capacity ?? throw new ArgumentNullException(nameof(capacity)); }
    public bool Execute(int units)
    {
        if (!CapacityRule.CanTake(units, capacity.Free)) return false;
        capacity.Commit(units); return true;
    }
}

Adapters/MemoryCapacity.cs

public sealed class MemoryCapacity : ICapacity
{
    public int Free { get; private set; }
    public int Commits { get; private set; }
    public MemoryCapacity(int free) { if (free < 0) throw new ArgumentOutOfRangeException(nameof(free)); Free = free; }
    public void Commit(int units)
    {
        if (!CapacityRule.CanTake(units, Free)) throw new InvalidOperationException("Invalid commit");
        Free -= units; Commits++;
    }
}

Checks/CapacityChecks.cs

public static class CapacityChecks
{
    public static List<(string Name, bool Passed)> Run()
    {
        List<(string Name, bool Passed)> checks = [];
        var accepted = new MemoryCapacity(3);
        checks.Add(("accept-two", new Reserve(accepted).Execute(2) && accepted.Free == 1 && accepted.Commits == 1));
        var exact = new MemoryCapacity(3);
        checks.Add(("exact", new Reserve(exact).Execute(3) && exact.Free == 0 && exact.Commits == 1));
        var excess = new MemoryCapacity(3);
        checks.Add(("excess", !new Reserve(excess).Execute(4) && excess.Free == 3 && excess.Commits == 0));
        var zero = new MemoryCapacity(3);
        checks.Add(("zero", !new Reserve(zero).Execute(0) && zero.Free == 3 && zero.Commits == 0));
        var repeated = new MemoryCapacity(3);
        var service = new Reserve(repeated);
        checks.Add(("rejection-preserves", service.Execute(2) && !service.Execute(2) && repeated.Free == 1 && repeated.Commits == 1));
        var negative = new MemoryCapacity(3);
        checks.Add(("negative", !new Reserve(negative).Execute(-1) && negative.Free == 3 && negative.Commits == 0));
        return checks;
    }
}

ConsoleLab.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <LangVersion>13.0</LangVersion>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>