Scoped Contexts
Scoped contexts let users navigate into sub-trees of your command graph — like cd for your app’s data model.
Defining contexts
Section titled “Defining contexts”app.Context("client", client =>{ client.Map("list", static (IContactStore store) => store.All());
client.Context("{id:int}", scoped => { scoped.Map("show", static (int id, IContactStore store) => store.Get(id)); scoped.Map("remove", static (int id, IContactStore store) => { store.Remove(id); return Results.Success("Removed."); }); });});The shape of this graph:
myapp└── client ├── list └── {id:int} ├── show └── removeREPL navigation
Section titled “REPL navigation”In REPL mode, enter a context by typing its name. Use .. to go up:
> client[client]> listAlice (1)Bob (2)
[client]> 1[client/1]> showId: 1 Name: Alice
[client/1]> ..[client]> ..>In CLI mode, the same routes work as a flat command:
myapp client 1 showmyapp client 1 removeDI-backed handlers
Section titled “DI-backed handlers”With ReplApp (vs. the lighter CoreReplApp), handlers can take DI-injected services:
var app = ReplApp.Create(services =>{ services.AddSingleton<IContactStore, ContactStore>();}).UseDefaultInteractive();
app.Context("client", client =>{ client.Map("list", (IContactStore store) => store.All());
client.Context("{id:int}", scoped => { scoped.Map("show", static (int id, IContactStore store) => store.Get(id)); });});
return app.Run(args);Parameters that match registered services are injected automatically. Parameters that match route segments are bound from the route.
Scoped state
Section titled “Scoped state”A context can carry state captured at navigation time:
client.Context("{id:int}", (int id, IContactStore store) =>{ var contact = store.Get(id) ?? throw new KeyNotFoundException($"Contact {id} not found.");
return scoped => { scoped.Map("show", () => contact); scoped.Map("update {name}", (string name) => { contact = contact with { Name = name }; store.Save(contact); }); };});The outer lambda resolves contact once when the scope is entered. All commands inside use that resolved value.
Completion providers
Section titled “Completion providers”Register a completion provider to populate Tab suggestions in REPL mode:
client.Context("{id:int}", scoped => { /* ... */ }) .WithCompletion((IContactStore store) => store.All().Select(c => new CompletionItem(c.Id.ToString(), c.Name)));Further reading
Section titled “Further reading”- Routes & Parameters — route constraint syntax, completion providers, and parameter binding.
- Modules — packaging reusable scope patterns into
IReplModuleclasses. - Dependency Injection — injecting services into scoped handlers.