public void Dispose(IHookContext ctx) /* free any unmanaged resources */

private readonly Stream _inner; private readonly THook _hook; private readonly IHookContext _ctx; // …

You can subscribe using:

// Then the inner stream is disposed (unless the hook says otherwise) _inner.Dispose(); base.Dispose(disposing);

public override async ValueTask<int> ReadAsync( Memory<byte> destination, CancellationToken cancellationToken = default)

// 3. Hook can post‑process the data (e.g., logging, decryption) _hook.AfterRead(_ctx, buffer, offset, bytesRead);

public sealed class LoggingHook : IStreamHook { public void BeforeRead(IHookContext ctx, byte[] buffer, int offset, int count) => Console.WriteLine($"[LOG] About to read