Add Dependency Injection integration #996
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This adds a Dependency Injection container which is used for all configuration options, actions and extensions
Motivation
Currently a custom dependency injection container is used for the gateway config, where config options, actions etc. are added to an
ArrayObject
instance. This has support for factories, which uses a function to construct a class and has access to all the values defined in the ArrayObject instance.This has been replaced with an external dependency injection container using PHP-DI.
Benefits
There are several benefits with using PHP-DI as a container:
$container->get(SomeClass::class)
and get an instance of the class with all the dependencies resolved without having to specify any configurationHaving a container providing services is already available in the Symfony and Laravel integration. This just adds it to Core so that we can benefit from Dependency Injection outside of any framework integration.
Side Effects
This implementation also has some side-effects:
We can no longer determine if a config value should be an action or an extension without iterating through the entire container definition.
This means we are deprecating the
payum.action.*
andpayum.extension.*
config optionsInstead, we introduce a new way to specify actions and extensions for a gateway by introducing a
GatewayFactoryConfigInterface
interfaceThis interface provides dedicated methods for actions and interfaces, and also provides a method for creating the gateway which has access to the container.
Here is an example from the
CoreGatewayFactory
:This also means we are deprecating the
GatewayFactoryInterface
in favour of theGatewayFactoryConfigInterface
.Usage
If a factory wants to provide it's own configuration for a container, the gateway factory can implement the
ContainerConfiguration
interface, which has the methodpublic function configureContainer(): array;
in order to define it's own container configuration (which will be merged with the config from CoreGateFactory), E.GIf you want to override or decorate an existing service (E.G provide you own implementation for the
GetCurrencyAction
), you can use the built-in features from PHP-DI:Important: The container instance is unique for each gateway. This means if you define a service on one gateway, then it won't be available in the container for another gateway.
Backward Compatibility
The current implementation is fully backward compatible with the current gateway configuration. This means that all existing gateways will continue working, and new gateways can implement the new interfaces and start using the new container. Existing gateways can also migrate to the newer container configuration whenever they want without any BC breaks.
TODO
This feature paves the way for much greater flexibility and additional features on the roadmap.
This is just a first-pass of the implementation. There are still lots to do, but opening this up now for some initial feedback