ReuseScope.Request

This is the cleanest and most testable approach with predictable behavior across all AppHosts, IOCs, etc as it’s not reliant on external environment thread request context switching implementations. A more testable approach would be to pass in the Request properties you need instead of IRequest but as that requires more code/effort, I prefer to just pass in IRequest when needed.

The GlobalRequestFilter (or any other Request filter) is what you’d use to inject any per-request dependencies in IRequest.Items at the start of the Request pipeline.

Injecting IRequest works in both transient and singleton dependencies given it’s how to make dependencies ThreadSafe by passing in local dependencies as arguments.

Lazy Properties

Other than you could have a lazy property in a Service base class which constructs the dependency with the IRequest context which is how all multi-tenancy aware dependencies in Service.cs are implemented, e.g:

private IDbConnection db;
public virtual IDbConnection Db => db ?? (db = AppHost.GetDbConnection(Request));

Where your Services would be able to access it like a normal dependency:

public object Any(MyRequest request) => Db.SingleById<Table>(request.Id);

If you adopt this approach you’ll need to manually dispose of your dependency if it needs disposing. If you didn’t want a base class you could wrap the construction logic behind extension methods instead.