How Performables get their dependencies
Importantly, Performable types do not participate in dependency injection from the container. This means that dependency services cannot be constructor-injected into performable types.
Performables' state represents parameters
Performables are created using the builder pattern and do not hold references to any dependency services. Instead, the state of the performable (and thus their constructor parameters) represent the parameters for the performable's behaviour. This state should be set via constructor parameters and should be immutable.
An example
For example, a Task which adds an item to the user's shopping basket might accept a constructor parameter representing the unique ID of the product to be added to the basket.
That unique ID would be stored within the performable instance, in a readonly field.
When the relevant ExecuteAsync method is executed, the unique ID stored in the performable instance is used to conduct whatever logic is appropriate.
Use abilities to get dependencies
Performables, specifcally Actions and Questions, should access their dependencies via the Actor's Abilities by using the GetAbility<T> method or similar.
In this sense, Abilities are a form of dependency injection or service locator (for a specific use case).
Whilst service locators are usually considered an anti-pattern, the benefits in this specific case outweigh the disadvantages.
The primary benefit is the ability to create performables from static builders.
Generally-speaking, Tasks should not make use of Abilities. Only Actions and Questions should use Abilities.