Injecting services
There are a few techniques in which injecting dependencies is relevant. These are summarised below. All but one of these techniques provide access to the services which are added to the container.
Into test logic
When using automated test logic based upon Screenplay, the use of dependency injection typically takes one of two forms. Which of these depends upon the nature and paradigm of the test framework.
For frameworks which are based on test methods such as NUnit, services are typically injected via method parameter injection into the test methods. If Screenplay were to be extended to work with frameworks such as xUnit or MSTest then this is likely to be the technique used.
For frameworks which are based on binding classes such as SpecFlow, services are constructor-injected into binding classes.
Use dependencies injected in this way to get access to commonly-used Screenplay services and anything else required at the root level of your test logic.
Into standalone performance logic
If you are using Screenplay standalone then the Screenplay.ExecuteAsPerformanceAsync
permits resolution of dependencies via its parameter.
That parameter is a Func<IServiceProvider,CancellationToken,Task<bool?>>
.
The service provider may be used to resolve dependency services for the performance's logic.
Developers are urged to consider encapsulating their performance logic in implementations of IHostsPerformance
.
Through an overload (extension method) named ExecuteAsPerformanceAsync<T>
, developers may specify the concrete implementation of that interface.
This extension method will resolve that implementation type along with any of its constructor-injected dependencies.
This avoids the service locator anti-pattern and provides a convenient pattern by which to write performance logic.
Use services resolved from the service provider, or injected into your IHostsPerformance
implementation, to get access to commonly-used Screenplay services and anything else required at the root level of your performance logic.
Into personas
Types which derive from IPersona
support constructor-injected dependencies.
Personas are typically used by either the cast or the stage to get an Actor.
The technique in which they are used means that they are resolved, along with their constructor-injected dependencies, from DI.
Use constructor-injected dependencies in persona classes to provide access to the APIs required to resolve Abilities that the actor is to be granted.
Into performables
See the article explaining how performables get their dependencies.