Plugins: Depending on other Plugins
Sometimes you need to rely on a service provided by another Plugin
or need to ensure that Plugin has done some other
thing before your Plugin will work correctly. Implementing the PluginDependentPlugin
will ensure that any other
Plugins you depend on will be loaded first.
Implementing PluginDependentPlugin
The very first thing that happens when a Plugin begins its loading process is to ensure that any other Plugins it may be
dependent on is finished with its own loading process. In our example we're going to create a Plugin that implements
InjectorAwarePlugin
that originates from a third-party library. We want to do something with the service that gets
registered. By depending on the Plugin that provides the service we can be sure it is available in the Injector
when
our Plugin begins its loading process.
<?php
namespace Acme\ThirdParty {
use Cspray\Labrador\Plugin\InjectorAwarePlugin;
use Auryn\Injector;
interface BarService {}
class StandardBarService implements BarService {}
class ThirdPartyServicePlugin implements InjectorAwarePlugin {
public function wireObjectGraph(Injector $injector) : void {
$injector->share(BarService::class);
$injector->alias(BarService::class, StandardBarService::class);
}
}
}
namespace Acme\MyApp {
use Cspray\Labrador\Plugin\BootablePlugin;
use Cspray\Labrador\Plugin\PluginDependentPlugin;
use Amp\Promise;
use Acme\ThirdParty\ThirdPartyServicePlugin;
use Acme\ThirdParty\BarService;
use function Amp\call;
class MyPlugin implements BootablePlugin, PluginDependentPlugin {
private $barService;
public function __construct(BarService $barService) {
$this->barService = $barService;
}
public static function dependsOn() : array {
return [ThirdPartyServicePlugin::class];
}
public function boot() : Promise {
return call(function() {
// We can do something with $this->barService now
});
}
}
}
Your Plugin doesn't have to implement the boot()
method. It is simply there to show that you can declare constructor
dependencies that are provided by the dependent Plugin. They will be injected automatically during the loading process
for your Plugin.
An astute observer would notice that this interface introduces a possibility for a circular dependency and an infinite
loop situation. The intricacies of the Plugin loading process, especially handling this interface, is tested and
well-handled by the PluginManager
implementation... including the problems with circular dependencies. You should let
the PluginManager
implementation handle the Plugin loading process in the vast majority of use cases.
Next Steps
Next up you should continue to learn more about Creating your DependencyGraph.