diff --git a/annotated-container.xsd b/annotated-container.xsd
index 1d8e9e87..7f65b3e4 100644
--- a/annotated-container.xsd
+++ b/annotated-container.xsd
@@ -33,7 +33,6 @@
-
@@ -75,12 +74,6 @@
-
-
-
-
-
-
diff --git a/composer.json b/composer.json
index 166005db..ad33edb2 100644
--- a/composer.json
+++ b/composer.json
@@ -54,7 +54,6 @@
},
"files": [
"fixture_src/VendorScanningInitializers/vendor/cspray/package/other_src/DependencyDefinitionProvider.php",
- "fixture_src/VendorScanningInitializers/vendor/cspray/package/src/DependencyObserver.php",
"fixture_src/VendorScanningInitializers/vendor/cspray/package/src/FirstInitializer.php",
"fixture_src/VendorScanningInitializers/vendor/cspray/package/src/SecondInitializer.php",
"fixture_src/VendorScanningInitializers/vendor/cspray/package/src/SomeService.php",
diff --git a/fixture_src/VendorScanningInitializers/vendor/cspray/package/src/DependencyObserver.php b/fixture_src/VendorScanningInitializers/vendor/cspray/package/src/DependencyObserver.php
deleted file mode 100644
index 76451b48..00000000
--- a/fixture_src/VendorScanningInitializers/vendor/cspray/package/src/DependencyObserver.php
+++ /dev/null
@@ -1,15 +0,0 @@
-get(SomeService::class)->setSomething('called from observer');
- }
-}
\ No newline at end of file
diff --git a/known-issues.xml b/known-issues.xml
index cfb9e21f..6c74dcdb 100644
--- a/known-issues.xml
+++ b/known-issues.xml
@@ -1,22 +1,5 @@
-
-
- ?ObserverFactory
- ObserverFactory
- PreAnalysisObserver|PostAnalysisObserver|ContainerCreatedObserver|ContainerAnalyticsObserver $observer
- array
- private array $observers = [];
-
-
- getObservers
-
-
-
-
- list<PreAnalysisObserver|PostAnalysisObserver|ContainerCreatedObserver|ContainerAnalyticsObserver>
-
-
$composerData['extra']
@@ -35,34 +18,13 @@
isDot
-
-
- PreAnalysisObserver|PostAnalysisObserver|ContainerCreatedObserver
-
-
-
-
- ServiceWiringObserver
-
-
- $services
-
-
- array
-
-
-
-
- array
- list<PreAnalysisObserver|PostAnalysisObserver|ContainerCreatedObserver|ContainerAnalyticsObserver>
- private
-
-
- new $observerClass()
-
-
- $observers
-
+
+
+ $service
+
+
+ $service
+
@@ -85,9 +47,6 @@
-
- getObserverClasses
-
$composer
$configName
@@ -109,13 +68,6 @@
-
- PostAnalysisObserver
- PostAnalysisObserver
-
-
- class($closure) implements PostAnalysisObserver {
-
$configOption
$configOption
diff --git a/phpunit.xml b/phpunit.xml
index 329abfc0..50ab67ff 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -29,7 +29,7 @@
-
+
diff --git a/src/Bootstrap/Bootstrap.php b/src/Bootstrap/Bootstrap.php
index b60ce272..70445286 100644
--- a/src/Bootstrap/Bootstrap.php
+++ b/src/Bootstrap/Bootstrap.php
@@ -6,6 +6,8 @@
use Cspray\AnnotatedContainer\AnnotatedContainer;
use Cspray\AnnotatedContainer\Definition\ContainerDefinition;
use Cspray\AnnotatedContainer\Event\BootstrapEmitter;
+use Cspray\AnnotatedContainer\Event\ContainerFactoryEmitter;
+use Cspray\AnnotatedContainer\Event\Emitter;
use Cspray\AnnotatedContainer\Profiles;
use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalyzer;
use Cspray\AnnotatedContainer\StaticAnalysis\CacheAwareContainerDefinitionAnalyzer;
@@ -35,31 +37,22 @@ final class Bootstrap {
private readonly ?DefinitionProviderFactory $definitionProviderFactory;
- private readonly ?ObserverFactory $observerFactory;
-
- private readonly ?ContainerFactory $containerFactory;
+ private readonly ContainerFactory $containerFactory;
private readonly Stopwatch $stopwatch;
- /**
- * @var list
- */
- private array $observers = [];
-
public function __construct(
+ ContainerFactory $containerFactory,
BootstrapEmitter $emitter = null,
BootstrappingDirectoryResolver $directoryResolver = null,
ParameterStoreFactory $parameterStoreFactory = null,
DefinitionProviderFactory $definitionProviderFactory = null,
- ObserverFactory $observerFactory = null,
Stopwatch $stopwatch = null,
- ContainerFactory $containerFactory = null
) {
$this->emitter = $emitter;
$this->directoryResolver = $directoryResolver ?? $this->defaultDirectoryResolver();
$this->parameterStoreFactory = $parameterStoreFactory ?? new DefaultParameterStoreFactory();
$this->definitionProviderFactory = $definitionProviderFactory;
- $this->observerFactory = $observerFactory;
$this->stopwatch = $stopwatch ?? new Stopwatch();
$this->containerFactory = $containerFactory;
}
@@ -73,10 +66,6 @@ private function defaultDirectoryResolver() : BootstrappingDirectoryResolver {
return new RootDirectoryBootstrappingDirectoryResolver($rootDir);
}
- public function addObserver(PreAnalysisObserver|PostAnalysisObserver|ContainerCreatedObserver|ContainerAnalyticsObserver $observer) : void {
- $this->observers[] = $observer;
- }
-
public function bootstrapContainer(
Profiles $profiles,
string $configurationFile = 'annotated-container.xml'
@@ -89,16 +78,9 @@ public function bootstrapContainer(
$this->emitter?->emitBeforeBootstrap($configuration);
- foreach ($configuration->getObservers() as $observer) {
- $this->addObserver($observer);
- }
-
- $this->notifyPreAnalysis($profiles);
-
$analysisPrepped = $this->stopwatch->mark();
$containerDefinition = $this->runStaticAnalysis($configuration, $analysisOptions);
- $this->notifyPostAnalysis($profiles, $containerDefinition);
$analysisCompleted = $this->stopwatch->mark();
@@ -108,11 +90,8 @@ public function bootstrapContainer(
$containerDefinition,
);
- $this->notifyContainerCreated($profiles, $containerDefinition, $container);
-
$metrics = $this->stopwatch->stop();
$analytics = $this->createAnalytics($metrics, $analysisPrepped, $analysisCompleted);
- $this->notifyAnalytics($analytics);
$this->emitter?->emitAfterBootstrap(
$configuration,
@@ -129,7 +108,6 @@ private function bootstrappingConfiguration(string $configurationFile) : Bootstr
return new XmlBootstrappingConfiguration(
$configFile,
parameterStoreFactory: $this->parameterStoreFactory,
- observerFactory: $this->observerFactory,
definitionProviderFactory: $this->definitionProviderFactory
);
}
@@ -149,14 +127,6 @@ private function analysisOptions(BootstrappingConfiguration $configuration) : Co
return $analysisOptions->build();
}
- private function notifyPreAnalysis(Profiles $activeProfiles) : void {
- foreach ($this->observers as $observer) {
- if ($observer instanceof PreAnalysisObserver) {
- $observer->notifyPreAnalysis($activeProfiles);
- }
- }
- }
-
private function runStaticAnalysis(
BootstrappingConfiguration $configuration,
ContainerDefinitionAnalysisOptions $analysisOptions
@@ -181,56 +151,18 @@ private function containerDefinitionAnalyzer(?string $cacheDir) : ContainerDefin
return $compiler;
}
- private function notifyPostAnalysis(Profiles $activeProfiles, ContainerDefinition $containerDefinition) : void {
- foreach ($this->observers as $observer) {
- if ($observer instanceof PostAnalysisObserver) {
- $observer->notifyPostAnalysis($activeProfiles, $containerDefinition);
- }
- }
- }
-
private function createContainer(
BootstrappingConfiguration $configuration,
Profiles $activeProfiles,
ContainerDefinition $containerDefinition,
) : AnnotatedContainer {
- $containerFactory = $this->containerFactory();
-
foreach ($configuration->getParameterStores() as $parameterStore) {
- $containerFactory->addParameterStore($parameterStore);
+ $this->containerFactory->addParameterStore($parameterStore);
}
$factoryOptions = ContainerFactoryOptionsBuilder::forProfiles($activeProfiles);
- return $containerFactory->createContainer($containerDefinition, $factoryOptions->build());
- }
-
- private function containerFactory() : ContainerFactory {
- if ($this->containerFactory !== null) {
- return $this->containerFactory;
- }
-
- if (class_exists(Injector::class)) {
- return new AurynContainerFactory();
- }
-
- if (class_exists(Container::class)) {
- return new PhpDiContainerFactory();
- }
-
- throw BackingContainerNotFound::fromMissingImplementation();
- }
-
- private function notifyContainerCreated(
- Profiles $activeProfiles,
- ContainerDefinition $containerDefinition,
- AnnotatedContainer $container
- ) : void {
- foreach ($this->observers as $observer) {
- if ($observer instanceof ContainerCreatedObserver) {
- $observer->notifyContainerCreated($activeProfiles, $containerDefinition, $container);
- }
- }
+ return $this->containerFactory->createContainer($containerDefinition, $factoryOptions->build());
}
private function createAnalytics(
@@ -246,12 +178,4 @@ private function createAnalytics(
);
}
- private function notifyAnalytics(ContainerAnalytics $analytics) : void {
- foreach ($this->observers as $observer) {
- if ($observer instanceof ContainerAnalyticsObserver) {
- $observer->notifyAnalytics($analytics);
- }
- }
- }
-
}
diff --git a/src/Bootstrap/BootstrappingConfiguration.php b/src/Bootstrap/BootstrappingConfiguration.php
index b816a14b..35b793bf 100644
--- a/src/Bootstrap/BootstrappingConfiguration.php
+++ b/src/Bootstrap/BootstrappingConfiguration.php
@@ -23,10 +23,4 @@ public function getContainerDefinitionProvider() : ?DefinitionProvider;
*/
public function getParameterStores() : array;
- /**
- * @return list
- * @deprecated
- */
- public function getObservers() : array;
-
}
diff --git a/src/Bootstrap/ContainerAnalyticsObserver.php b/src/Bootstrap/ContainerAnalyticsObserver.php
deleted file mode 100644
index e72e2e26..00000000
--- a/src/Bootstrap/ContainerAnalyticsObserver.php
+++ /dev/null
@@ -1,12 +0,0 @@
-containerDefinition = new ProfilesAwareContainerDefinition($containerDefinition, $activeProfiles);
}
+ /**
+ * @param class-string $type
+ * @return list
+ */
public function getServicesForType(string $type) : array {
- /** @var array $services */
+ /** @var list $services */
$services = [];
foreach ($this->containerDefinition->getServiceDefinitions() as $serviceDefinition) {
if ($serviceDefinition->isAbstract()) {
@@ -85,7 +89,4 @@ public function getDefinition() : ServiceDefinition {
};
$this->wireServices($container, $serviceGatherer);
}
-
- abstract protected function wireServices(AnnotatedContainer $container, ServiceGatherer $gatherer) : void;
-
}
\ No newline at end of file
diff --git a/src/Bootstrap/ThirdPartyInitializer.php b/src/Bootstrap/ThirdPartyInitializer.php
index bc0cdbfb..a2a0beb4 100644
--- a/src/Bootstrap/ThirdPartyInitializer.php
+++ b/src/Bootstrap/ThirdPartyInitializer.php
@@ -13,12 +13,6 @@ abstract public function getPackageName() : string;
*/
abstract public function getRelativeScanDirectories() : array;
- /**
- * @return list
- * @deprecated
- */
- abstract public function getObserverClasses() : array;
-
abstract public function getDefinitionProviderClass() : ?string;
}
\ No newline at end of file
diff --git a/src/Bootstrap/XmlBootstrappingConfiguration.php b/src/Bootstrap/XmlBootstrappingConfiguration.php
index 50ad2540..2373b002 100644
--- a/src/Bootstrap/XmlBootstrappingConfiguration.php
+++ b/src/Bootstrap/XmlBootstrappingConfiguration.php
@@ -28,15 +28,9 @@ final class XmlBootstrappingConfiguration implements BootstrappingConfiguration
*/
private readonly array $parameterStores;
- /**
- * @var list
- */
- private readonly array $observers;
-
public function __construct(
private readonly string $xmlFile,
private readonly ?ParameterStoreFactory $parameterStoreFactory = null,
- private readonly ?ObserverFactory $observerFactory = null,
private readonly ?DefinitionProviderFactory $definitionProviderFactory = null
) {
if (!file_exists($this->xmlFile)) {
@@ -134,23 +128,6 @@ public function __construct(
}
}
- $observers = [];
- $observerNodes = $xpath->query('/ac:annotatedContainer/ac:observers/ac:observer/text()');
- if ($observerNodes instanceof DOMNodeList) {
- foreach ($observerNodes as $observerNode) {
- $observerClass = (string) $observerNode->nodeValue;
- if (isset($this->observerFactory)) {
- $observer = $this->observerFactory->createObserver($observerClass);
- } else {
- if (!$this->isObserverType($observerClass)) {
- throw InvalidBootstrapConfiguration::fromConfiguredObserverWrongType($observerClass);
- }
- $observer = new $observerClass();
- }
- $observers[] = $observer;
- }
- }
-
/** @var DOMNodeList $cacheDirNodes */
$cacheDirNodes = $xpath->query('/ac:annotatedContainer/ac:cacheDir');
$cache = null;
@@ -162,25 +139,12 @@ public function __construct(
$this->definitionProvider = $definitionProvider;
$this->cacheDir = $cache;
$this->parameterStores = $parameterStores;
- $this->observers = $observers;
} finally {
libxml_clear_errors();
libxml_use_internal_errors(false);
}
}
- private function isObserverType(string $observerClass) : bool {
- if (!class_exists($observerClass)) {
- return false;
- }
-
- return is_subclass_of($observerClass, PreAnalysisObserver::class) ||
- is_subclass_of($observerClass, PostAnalysisObserver::class) ||
- is_subclass_of($observerClass, ContainerCreatedObserver::class) ||
- is_subclass_of($observerClass, ContainerAnalyticsObserver::class);
-
- }
-
public function getScanDirectories() : array {
return $this->directories;
}
@@ -201,11 +165,4 @@ public function getCacheDirectory() : ?string {
return $this->cacheDir;
}
- /**
- * @return list
- * @deprecated
- */
- public function getObservers() : array {
- return $this->observers;
- }
-}
\ No newline at end of file
+}
diff --git a/src/Cli/Command/InitCommand.php b/src/Cli/Command/InitCommand.php
index e426051e..6071f1fb 100644
--- a/src/Cli/Command/InitCommand.php
+++ b/src/Cli/Command/InitCommand.php
@@ -340,17 +340,6 @@ private function generateAndSaveConfiguration(Input $input, array $composer, str
}
}
- /** @var string|array|null $observers */
- $observers = $input->getOption('observer');
- $observersNode = $root->appendChild($dom->createElementNS(self::XML_SCHEMA, 'observers'));
- if ($observers !== null) {
- $observers = is_string($observers) ? [$observers] : $observers;
- /** @var string $observer */
- foreach ($observers as $observer) {
- $observersNode->appendChild($dom->createElementNS(self::XML_SCHEMA, 'observer', $observer));
- }
- }
-
$vendor = $scanDirectories->appendChild(
$dom->createElementNS(self::XML_SCHEMA, 'vendor')
);
@@ -381,12 +370,6 @@ private function generateAndSaveConfiguration(Input $input, array $composer, str
$dom->createElementNS(self::XML_SCHEMA, 'definitionProvider', $providerClass)
);
}
-
- foreach ($thirdPartyInitializer->getObserverClasses() as $observerClass) {
- $observersNode->appendChild(
- $dom->createElementNS(self::XML_SCHEMA, 'observer', $observerClass)
- );
- }
}
/** @var string|null $cacheDirOpt */
diff --git a/src/Cli/Command/ValidateCommand.php b/src/Cli/Command/ValidateCommand.php
index 6095574a..f6f812ab 100644
--- a/src/Cli/Command/ValidateCommand.php
+++ b/src/Cli/Command/ValidateCommand.php
@@ -6,7 +6,9 @@
use Cspray\AnnotatedContainer\AnnotatedContainer;
use Cspray\AnnotatedContainer\Autowire\AutowireableParameterSet;
use Cspray\AnnotatedContainer\Bootstrap\Bootstrap;
+use Cspray\AnnotatedContainer\Bootstrap\BootstrappingConfiguration;
use Cspray\AnnotatedContainer\Bootstrap\BootstrappingDirectoryResolver;
+use Cspray\AnnotatedContainer\Bootstrap\ContainerAnalytics;
use Cspray\AnnotatedContainer\Bootstrap\PostAnalysisObserver;
use Cspray\AnnotatedContainer\Cli\Command;
use Cspray\AnnotatedContainer\Cli\Exception\ConfigurationNotFound;
@@ -16,6 +18,8 @@
use Cspray\AnnotatedContainer\ContainerFactory\ContainerFactoryOptions;
use Cspray\AnnotatedContainer\ContainerFactory\ParameterStore;
use Cspray\AnnotatedContainer\Definition\ContainerDefinition;
+use Cspray\AnnotatedContainer\Event\Emitter;
+use Cspray\AnnotatedContainer\Event\Listener\Bootstrap\AfterBootstrap;
use Cspray\AnnotatedContainer\Exception\UnsupportedOperation;
use Cspray\AnnotatedContainer\LogicalConstraint\Check\DuplicateServiceDelegate;
use Cspray\AnnotatedContainer\LogicalConstraint\Check\DuplicateServiceName;
@@ -122,17 +126,21 @@ public function handle(Input $input, TerminalOutput $output) : int {
throw ConfigurationNotFound::fromMissingFile($configFile);
}
+ $emitter = new Emitter();
+
$bootstrap = new Bootstrap(
+ emitter: $emitter,
directoryResolver: $this->directoryResolver,
containerFactory: $this->noOpContainerFactory()
);
$containerDefinition = null;
- $infoCapturingObserver = $this->infoCapturingObserver(static function(ContainerDefinition $definition) use(&$containerDefinition) {
+ $infoCapturingListener = $this->infoCapturingListener(static function(ContainerDefinition $definition) use(&$containerDefinition) {
$containerDefinition = $definition;
});
- $bootstrap->addObserver($infoCapturingObserver);
+
+ $emitter->addAfterBootstrapListener($infoCapturingListener);
$inputProfiles = $input->getOption('profile') ?? ['default'];
if (is_string($inputProfiles)) {
@@ -191,23 +199,23 @@ public function createContainer(ContainerDefinition $containerDefinition, Contai
return new class implements AnnotatedContainer {
public function getBackingContainer() : object {
- throw UnsupportedOperation::fromMethodNotSupported(__METHOD__);
+ throw new \RuntimeException(__METHOD__);
}
public function make(string $classType, AutowireableParameterSet $parameters = null) : object {
- throw UnsupportedOperation::fromMethodNotSupported(__METHOD__);
+ throw new \RuntimeException(__METHOD__);
}
public function invoke(callable $callable, AutowireableParameterSet $parameters = null) : mixed {
- throw UnsupportedOperation::fromMethodNotSupported(__METHOD__);
+ throw new \RuntimeException(__METHOD__);
}
public function get(string $id) {
- throw UnsupportedOperation::fromMethodNotSupported(__METHOD__);
+ throw new \RuntimeException(__METHOD__);
}
public function has(string $id) : bool {
- throw UnsupportedOperation::fromMethodNotSupported(__METHOD__);
+ throw new \RuntimeException(__METHOD__);
}
};
}
@@ -219,10 +227,10 @@ public function addParameterStore(ParameterStore $parameterStore) : void {
/**
* @param Closure(ContainerDefinition):void $closure
- * @return PostAnalysisObserver
+ * @return AfterBootstrap
*/
- private function infoCapturingObserver(Closure $closure) : PostAnalysisObserver {
- return new class($closure) implements PostAnalysisObserver {
+ private function infoCapturingListener(Closure $closure) : AfterBootstrap {
+ return new class($closure) implements AfterBootstrap {
/**
* @param Closure(ContainerDefinition):void $closure
*/
@@ -230,7 +238,7 @@ public function __construct(
private readonly Closure $closure
) {}
- public function notifyPostAnalysis(Profiles $activeProfiles, ContainerDefinition $containerDefinition) : void {
+ public function handleAfterBootstrap(BootstrappingConfiguration $bootstrappingConfiguration, ContainerDefinition $containerDefinition, AnnotatedContainer $container, ContainerAnalytics $containerAnalytics) : void {
($this->closure)($containerDefinition);
}
};
diff --git a/src/ContainerFactory/AbstractContainerFactory.php b/src/ContainerFactory/AbstractContainerFactory.php
index 6187c64a..96a027b6 100644
--- a/src/ContainerFactory/AbstractContainerFactory.php
+++ b/src/ContainerFactory/AbstractContainerFactory.php
@@ -12,6 +12,7 @@
use Cspray\AnnotatedContainer\Definition\ServiceDefinition;
use Cspray\AnnotatedContainer\Definition\ServiceDelegateDefinition;
use Cspray\AnnotatedContainer\Definition\ServicePrepareDefinition;
+use Cspray\AnnotatedContainer\Event\ContainerFactoryEmitter;
use Cspray\AnnotatedContainer\Exception\ParameterStoreNotFound;
use Cspray\AnnotatedContainer\Profiles;
use Cspray\Typiphy\ObjectType;
@@ -21,6 +22,7 @@ abstract class AbstractContainerFactory implements ContainerFactory {
protected readonly AliasDefinitionResolver $aliasDefinitionResolver;
+ private readonly ?ContainerFactoryEmitter $emitter;
/**
* @var ParameterStore[]
@@ -28,21 +30,28 @@ abstract class AbstractContainerFactory implements ContainerFactory {
private array $parameterStores = [];
public function __construct(
- AliasDefinitionResolver $aliasDefinitionResolver = null
+ ContainerFactoryEmitter $emitter = null,
+ AliasDefinitionResolver $aliasDefinitionResolver = null,
) {
// Injecting environment variables is something we have supported since early versions.
// We don't require adding this parameter store explicitly to continue providing this functionality
// without the end-user having to change how they construct their ContainerFactory.
$this->addParameterStore(new EnvironmentParameterStore());
$this->aliasDefinitionResolver = $aliasDefinitionResolver ?? new StandardAliasDefinitionResolver();
+ $this->emitter = $emitter;
}
final public function createContainer(ContainerDefinition $containerDefinition, ContainerFactoryOptions $containerFactoryOptions = null) : AnnotatedContainer {
$activeProfiles = $containerFactoryOptions?->getProfiles() ?? Profiles::fromList(['default']);
- $state = $this->createContainerState($containerDefinition, $activeProfiles);
+ $this->emitter?->emitBeforeContainerCreation($activeProfiles, $containerDefinition);
- $container = $this->createAnnotatedContainer($state, $activeProfiles);
+ $container = $this->createAnnotatedContainer(
+ $this->createContainerState($containerDefinition, $activeProfiles),
+ $activeProfiles
+ );
+
+ $this->emitter?->emitAfterContainerCreation($activeProfiles, $containerDefinition, $container);
return $container;
}
diff --git a/src/ContainerFactory/IlluminateContainerFactory.php b/src/ContainerFactory/IlluminateContainerFactory.php
index 8cec9a7c..cafdc1b2 100644
--- a/src/ContainerFactory/IlluminateContainerFactory.php
+++ b/src/ContainerFactory/IlluminateContainerFactory.php
@@ -12,6 +12,7 @@
use Cspray\AnnotatedContainer\Definition\ServiceDefinition;
use Cspray\AnnotatedContainer\Definition\ServiceDelegateDefinition;
use Cspray\AnnotatedContainer\Definition\ServicePrepareDefinition;
+use Cspray\AnnotatedContainer\Event\ContainerFactoryEmitter;
use Cspray\AnnotatedContainer\Exception\ServiceNotFound;
use Cspray\AnnotatedContainer\Profiles;
use Cspray\Typiphy\ObjectType;
@@ -22,9 +23,11 @@ final class IlluminateContainerFactory extends AbstractContainerFactory {
public function __construct(
private readonly Container $container = new \Illuminate\Container\Container(),
- AliasDefinitionResolver $aliasDefinitionResolver = null
+ ContainerFactoryEmitter $emitter = null,
+ AliasDefinitionResolver $aliasDefinitionResolver = null,
+
) {
- parent::__construct($aliasDefinitionResolver);
+ parent::__construct($emitter, $aliasDefinitionResolver);
}
protected function getContainerFactoryState() : ContainerFactoryState {
diff --git a/src/Exception/BackingContainerNotFound.php b/src/Exception/BackingContainerNotFound.php
deleted file mode 100644
index 246864c2..00000000
--- a/src/Exception/BackingContainerNotFound.php
+++ /dev/null
@@ -1,11 +0,0 @@
-withContent($goodXml)
->at($this->vfs);
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
+ $bootstrap = new Bootstrap(
+ new AurynContainerFactory(), directoryResolver: $directoryResolver
+ );
$container = $bootstrap->bootstrapContainer(Profiles::fromList(['default']));
$service = $container->get(Fixtures::singleConcreteService()->fooImplementation()->getName());
@@ -96,7 +101,10 @@ public function testBootstrapSingleConcreteServiceWithCache() : void {
VirtualFilesystem::newDirectory('.annotated-container-cache')
->at($this->vfs);
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
+ $bootstrap = new Bootstrap(
+ new AurynContainerFactory(),
+ directoryResolver: $directoryResolver
+ );
$bootstrap->bootstrapContainer(Profiles::fromList(['default']));
$expected = md5(Fixtures::singleConcreteService()->getPath());
@@ -124,7 +132,10 @@ public function testBootstrapWithValidDefinitionProvider() : void {
->withContent($goodXml)
->at($this->vfs);
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
+ $bootstrap = new Bootstrap(
+ new AurynContainerFactory(),
+ directoryResolver: $directoryResolver
+ );
$container = $bootstrap->bootstrapContainer(Profiles::fromList(['default']));
$service = $container->get(Fixtures::thirdPartyServices()->fooInterface()->getName());
@@ -152,7 +163,10 @@ public function testBootstrapWithParameterStores() : void {
->withContent($goodXml)
->at($this->vfs);
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
+ $bootstrap = new Bootstrap(
+ new AurynContainerFactory(),
+ directoryResolver: $directoryResolver
+ );
$container = $bootstrap->bootstrapContainer(Profiles::fromList(['default']));
$service = $container->get(Fixtures::injectCustomStoreServices()->scalarInjector()->getName());
@@ -178,7 +192,10 @@ public function testBootstrapResolvesProfileServices() : void {
->withContent($goodXml)
->at($this->vfs);
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
+ $bootstrap = new Bootstrap(
+ new AurynContainerFactory(),
+ directoryResolver: $directoryResolver
+ );
$container = $bootstrap->bootstrapContainer(profiles: Profiles::fromList(['default', 'dev']));
$service = $container->get(Fixtures::profileResolvedServices()->fooInterface()->getName());
self::assertInstanceOf(Fixtures::profileResolvedServices()->devImplementation()->getName(), $service);
@@ -202,7 +219,10 @@ public function testBootstrapSingleConcreteServiceUsesCustomFileName() : void {
->withContent($goodXml)
->at($this->vfs);
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
+ $bootstrap = new Bootstrap(
+ new AurynContainerFactory(),
+ directoryResolver: $directoryResolver
+ );
$container = $bootstrap->bootstrapContainer(profiles: Profiles::fromList(['default']), configurationFile: 'my-container.xml.dist');
$service = $container->get(Fixtures::singleConcreteService()->fooImplementation()->getName());
@@ -245,7 +265,11 @@ public function createProvider(string $identifier) : DefinitionProvider {
}
};
- $container = (new Bootstrap(directoryResolver: $directoryResolver, definitionProviderFactory: $factory))->bootstrapContainer(Profiles::fromList(['default']));
+ $container = (new Bootstrap(
+ new AurynContainerFactory(),
+ directoryResolver: $directoryResolver,
+ definitionProviderFactory: $factory
+ ))->bootstrapContainer(Profiles::fromList(['default']));
$service = $container->get(Fixtures::thirdPartyServices()->fooInterface()->getName());
@@ -284,107 +308,17 @@ public function createParameterStore(string $identifier) : ParameterStore {
}
};
- $container = (new Bootstrap(directoryResolver: $directoryResolver, parameterStoreFactory: $factory))->bootstrapContainer(Profiles::fromList(['default']));
+ $container = (new Bootstrap(
+ new AurynContainerFactory(),
+ directoryResolver: $directoryResolver,
+ parameterStoreFactory: $factory
+ ))->bootstrapContainer(Profiles::fromList(['default']));
$service = $container->get(Fixtures::injectCustomStoreServices()->scalarInjector()->getName());
self::assertSame('ac-ackey', $service->key);
}
- public function testBootstrapObserverInvokedCorrectOrder() : void {
- $directoryResolver = new FixtureBootstrappingDirectoryResolver();
-
- $goodXml = <<
-
-
-
- SingleConcreteService
-
-
-
-XML;
-
- VirtualFilesystem::newFile('annotated-container.xml')
- ->withContent($goodXml)
- ->at($this->vfs);
-
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
-
- $bootstrap->addObserver($subject = new StubBootstrapObserver());
-
- $bootstrap->bootstrapContainer(Profiles::fromList(['default']));
-
- self::assertCount(3, $subject->getInvokedMethods());
- self::assertSame([
- [sprintf('%s::%s', StubBootstrapObserver::class, 'notifyPreAnalysis')],
- [sprintf('%s::%s', StubBootstrapObserver::class, 'notifyPostAnalysis')],
- [sprintf('%s::%s', StubBootstrapObserver::class, 'notifyContainerCreated')]
- ], $subject->getInvokedMethods());
- }
-
- public function testBootstrapMultipleObservers() : void {
- $directoryResolver = new FixtureBootstrappingDirectoryResolver();
-
- $goodXml = <<
-
-
-
- SingleConcreteService
-
-
-
-XML;
-
- VirtualFilesystem::newFile('annotated-container.xml')
- ->withContent($goodXml)
- ->at($this->vfs);
-
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
-
- $bootstrap->addObserver($one = new StubBootstrapObserver());
- $bootstrap->addObserver($two = new StubBootstrapObserver());
- $bootstrap->addObserver($three = new StubBootstrapObserver());
-
- $bootstrap->bootstrapContainer(Profiles::fromList(['default']));
-
- self::assertCount(3, $one->getInvokedMethods());
- self::assertCount(3, $two->getInvokedMethods());
- self::assertCount(3, $three->getInvokedMethods());
- }
-
- public function testObserversAddedFromConfiguration() : void {
- $directoryResolver = new FixtureBootstrappingDirectoryResolver();
-
- $goodXml = <<
-
-
-
- SingleConcreteService
-
-
-
- Cspray\AnnotatedContainer\Unit\Helper\StubBootstrapObserver
-
-
-XML;
-
- VirtualFilesystem::newFile('annotated-container.xml')
- ->withContent($goodXml)
- ->at($this->vfs);
-
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
- $bootstrap->bootstrapContainer(Profiles::fromList(['default']));
-
- $observers = (new \ReflectionObject($bootstrap))->getProperty('observers')->getValue($bootstrap);
-
- self::assertCount(1, $observers);
- self::assertInstanceOf(StubBootstrapObserver::class, $observers[0]);
- self::assertCount(3, $observers[0]->getInvokedMethods());
- }
-
public function testServiceWiringObserver() : void {
$directoryResolver = new FixtureBootstrappingDirectoryResolver();
@@ -403,9 +337,15 @@ public function testServiceWiringObserver() : void {
->withContent($goodXml)
->at($this->vfs);
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
+ $emitter = new Emitter();
+
+ $bootstrap = new Bootstrap(
+ new AurynContainerFactory($emitter),
+ emitter: $emitter,
+ directoryResolver: $directoryResolver
+ );
- $observer = new class extends ServiceWiringObserver {
+ $listener = new class extends ServiceWiringListener {
private ?AnnotatedContainer $container = null;
private array $services = [];
@@ -423,17 +363,18 @@ protected function wireServices(AnnotatedContainer $container, ServiceGatherer $
$this->services = $gatherer->getServicesForType(Fixtures::ambiguousAliasedServices()->fooInterface()->getName());
}
};
- $bootstrap->addObserver($observer);
+
+ $emitter->addAfterContainerCreationListener($listener);
$container = $bootstrap->bootstrapContainer(Profiles::fromList(['default']));
- $actual = $observer->getServices();
+ $actual = $listener->getServices();
$actualServices = array_map(fn(ServiceFromServiceDefinition $fromServiceDefinition) => $fromServiceDefinition->getService(), $actual);
usort($actualServices, fn($a, $b) => $a::class <=> $b::class);
- self::assertSame($container, $observer->getAnnotatedContainer());
+ self::assertSame($container, $listener->getAnnotatedContainer());
self::assertSame([
$container->get(Fixtures::ambiguousAliasedServices()->barImplementation()->getName()),
$container->get(Fixtures::ambiguousAliasedServices()->bazImplementation()->getName()),
@@ -459,9 +400,15 @@ public function testServiceWiringObserverByAttributes() : void {
->withContent($goodXml)
->at($this->vfs);
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
+ $emitter = new Emitter();
+
+ $bootstrap = new Bootstrap(
+ new AurynContainerFactory($emitter),
+ emitter: $emitter,
+ directoryResolver: $directoryResolver
+ );
- $observer = new class extends ServiceWiringObserver {
+ $listener = new class extends ServiceWiringListener {
private ?AnnotatedContainer $container = null;
private array $services = [];
@@ -479,14 +426,15 @@ protected function wireServices(AnnotatedContainer $container, ServiceGatherer $
$this->services = $gatherer->getServicesWithAttribute(Repository::class);
}
};
- $bootstrap->addObserver($observer);
+
+ $emitter->addAfterContainerCreationListener($listener);
$container = $bootstrap->bootstrapContainer(Profiles::fromList(['default', 'test']));
- $actual = $observer->getServices();
+ $actual = $listener->getServices();
$actualServices = array_map(fn(ServiceFromServiceDefinition $fromServiceDefinition) => $fromServiceDefinition->getService(), $actual);
- self::assertSame($container, $observer->getAnnotatedContainer());
+ self::assertSame($container, $listener->getAnnotatedContainer());
self::assertSame([
$container->get(Fixtures::customServiceAttribute()->myRepo()->getName()),
], $actualServices);
@@ -510,9 +458,15 @@ public function testServiceWiringObserverByTypeProfileAware() : void {
->withContent($goodXml)
->at($this->vfs);
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
+ $emitter = new Emitter();
- $observer = new class extends ServiceWiringObserver {
+ $bootstrap = new Bootstrap(
+ new AurynContainerFactory($emitter),
+ emitter: $emitter,
+ directoryResolver: $directoryResolver
+ );
+
+ $listener = new class extends ServiceWiringListener {
private ?AnnotatedContainer $container = null;
private array $services = [];
@@ -530,17 +484,18 @@ protected function wireServices(AnnotatedContainer $container, ServiceGatherer $
$this->services = $gatherer->getServicesForType(Fixtures::profileResolvedServices()->fooInterface()->getName());
}
};
- $bootstrap->addObserver($observer);
+
+ $emitter->addAfterContainerCreationListener($listener);
$container = $bootstrap->bootstrapContainer(Profiles::fromList(['default', 'prod']));
- $actual = $observer->getServices();
+ $actual = $listener->getServices();
$actualServices = array_map(fn(ServiceFromServiceDefinition $fromServiceDefinition) => $fromServiceDefinition->getService(), $actual);
usort($actualServices, fn($a, $b) => $a::class <=> $b::class);
- self::assertSame($container, $observer->getAnnotatedContainer());
+ self::assertSame($container, $listener->getAnnotatedContainer());
self::assertSame([
$container->get(Fixtures::profileResolvedServices()->prodImplementation()->getName()),
], $actualServices);
@@ -564,9 +519,15 @@ public function testServiceWiringObserverByAttributesProfileAware() : void {
->withContent($goodXml)
->at($this->vfs);
- $bootstrap = new Bootstrap(directoryResolver: $directoryResolver);
+ $emitter = new Emitter();
+
+ $bootstrap = new Bootstrap(
+ new AurynContainerFactory($emitter),
+ emitter: $emitter,
+ directoryResolver: $directoryResolver
+ );
- $observer = new class extends ServiceWiringObserver {
+ $listener = new class extends ServiceWiringListener {
private ?AnnotatedContainer $container = null;
private array $services = [];
@@ -584,88 +545,14 @@ protected function wireServices(AnnotatedContainer $container, ServiceGatherer $
$this->services = $gatherer->getServicesWithAttribute(Repository::class);
}
};
- $bootstrap->addObserver($observer);
+
+ $emitter->addAfterContainerCreationListener($listener);
// The Repository is only active under 'test' profile and should not be included
$container = $bootstrap->bootstrapContainer(Profiles::fromList(['default', 'dev']));
- self::assertSame($container, $observer->getAnnotatedContainer());
- self::assertEmpty($observer->getServices());
- }
-
- public function testObserverFactoryRespected() : void {
- $directoryResolver = new FixtureBootstrappingDirectoryResolver();
-
- $goodXml = <<
-
-
-
- SingleConcreteService
-
-
-
- Passed to ObserverFactory
-
-
-XML;
-
- VirtualFilesystem::newFile('annotated-container.xml')
- ->withContent($goodXml)
- ->at($this->vfs);
-
- $observerFactory = $this->getMockBuilder(ObserverFactory::class)->getMock();
- $observerFactory->expects($this->once())
- ->method('createObserver')
- ->with('Passed to ObserverFactory')
- ->willReturn($this->getMockBuilder(PreAnalysisObserver::class)->getMock());
-
- (new Bootstrap(
- directoryResolver: $directoryResolver,
- observerFactory: $observerFactory
- ))->bootstrapContainer(Profiles::fromList(['default']));
- }
-
- public function testContainerAnalyticsObserverNotifiedAfterContainerCreated() : void {
- $directoryResolver = new FixtureBootstrappingDirectoryResolver();
-
- $goodXml = <<
-
-
-
- SingleConcreteService
-
-
-
-XML;
-
- VirtualFilesystem::newFile('annotated-container.xml')
- ->withContent($goodXml)
- ->at($this->vfs);
-
- $observer = new class implements ContainerCreatedObserver, ContainerAnalyticsObserver {
- private array $calls = [];
-
- public function notifyAnalytics(ContainerAnalytics $analytics) : void {
- $this->calls[] = __FUNCTION__;
- }
-
- public function notifyContainerCreated(Profiles $activeProfiles, ContainerDefinition $containerDefinition, AnnotatedContainer $container) : void {
- $this->calls[] = __FUNCTION__;
- }
-
- public function getCalls() : array {
- return $this->calls;
- }
- };
-
- $subject = new Bootstrap(directoryResolver: $directoryResolver);
- $subject->addObserver($observer);
-
- $subject->bootstrapContainer(Profiles::fromList(['default']));
-
- self::assertSame(['notifyContainerCreated', 'notifyAnalytics'], $observer->getCalls());
+ self::assertSame($container, $listener->getAnnotatedContainer());
+ self::assertEmpty($listener->getServices());
}
public function testContainerAnalyticsHasExpectedTotalDuration() : void {
@@ -686,27 +573,32 @@ public function testContainerAnalyticsHasExpectedTotalDuration() : void {
->withContent($goodXml)
->at($this->vfs);
- $observer = new class implements ContainerAnalyticsObserver {
- private ?ContainerAnalytics $analytics = null;
+ $emitter = new Emitter();
- public function notifyAnalytics(ContainerAnalytics $analytics) : void {
- $this->analytics = $analytics;
- }
+ $listener = new class implements AfterBootstrap {
+ private ?ContainerAnalytics $analytics = null;
public function getAnalytics() : ?ContainerAnalytics {
return $this->analytics;
}
+
+ public function handleAfterBootstrap(BootstrappingConfiguration $bootstrappingConfiguration, ContainerDefinition $containerDefinition, AnnotatedContainer $container, ContainerAnalytics $containerAnalytics,) : void {
+ $this->analytics = $containerAnalytics;
+ }
};
$subject = new Bootstrap(
+ new AurynContainerFactory(),
+ emitter: $emitter,
directoryResolver: $directoryResolver,
stopwatch: new Stopwatch(new KnownIncrementingPreciseTime())
);
- $subject->addObserver($observer);
+
+ $emitter->addAfterBootstrapListener($listener);
$subject->bootstrapContainer(Profiles::fromList(['default']));
- $analytics = $observer->getAnalytics();
+ $analytics = $listener->getAnalytics();
self::assertNotNull($analytics);
self::assertSame(3, $analytics->totalTime->timeTakenInNanoseconds());
@@ -715,38 +607,6 @@ public function getAnalytics() : ?ContainerAnalytics {
self::assertSame(1, $analytics->timeTakenCreatingContainer->timeTakenInNanoseconds());
}
- public function testContainerAnalyticsObserverInConfigurationRespected() : void {
- $directoryResolver = new FixtureBootstrappingDirectoryResolver();
-
- $goodXml = <<
-
-
-
- SingleConcreteService
-
-
-
- Cspray\AnnotatedContainer\Unit\Helper\StubAnalyticsObserver
-
-
-XML;
-
- VirtualFilesystem::newFile('annotated-container.xml')
- ->withContent($goodXml)
- ->at($this->vfs);
-
- $subject = new Bootstrap(
- directoryResolver: $directoryResolver,
- );
-
- StubAnalyticsObserver::$analytics = null;
-
- $subject->bootstrapContainer(Profiles::fromList(['default']));
-
- self::assertNotNull(StubAnalyticsObserver::$analytics);
- }
-
public function testContainerFactoryPassedToConstructorTakesPriority() : void {
$directoryResolver = new FixtureBootstrappingDirectoryResolver();
@@ -803,7 +663,11 @@ public function testBootstrapEventsTriggeredInCorrectOrder() : void {
$emitter->addBeforeBootstrapListener($listener);
$emitter->addAfterBootstrapListener($listener);
- $bootstrap = new Bootstrap(emitter: $emitter, directoryResolver: $directoryResolver);
+ $bootstrap = new Bootstrap(
+ new AurynContainerFactory(),
+ emitter: $emitter,
+ directoryResolver: $directoryResolver
+ );
$bootstrap->bootstrapContainer(Profiles::fromList(['default']));
self::assertSame(
diff --git a/test/Unit/Cli/Command/InitCommandTest.php b/test/Unit/Cli/Command/InitCommandTest.php
index cb3d4a92..4fe0d923 100644
--- a/test/Unit/Cli/Command/InitCommandTest.php
+++ b/test/Unit/Cli/Command/InitCommandTest.php
@@ -295,9 +295,6 @@ public function testInitDefaultFileComposerJsonPresentCreatesConfigurationFile()
Cspray\AnnotatedContainerFixture\VendorScanningInitializers\DependencyDefinitionProvider
-
- Cspray\AnnotatedContainerFixture\VendorScanningInitializers\DependencyObserver
-
.annotated-container-cache
@@ -355,7 +352,6 @@ public function testDefaultInitTakesConfigurationNameFromOption() : void {
-
.annotated-container-cache
@@ -399,7 +395,6 @@ public function testConfigFileFromComposerRespected() : void {
-
.annotated-container-cache
@@ -461,7 +456,6 @@ public function testHandlesCacheDirAlreadyPresent() : void {
-
.annotated-container-cache
@@ -502,7 +496,6 @@ public function testRespectCacheDirProvidedAsOption() : void {
-
my-cache-dir
@@ -544,7 +537,6 @@ public function testRespectsNestedCacheDir() : void {
-
path/cache/my-cache-dir
@@ -580,7 +572,6 @@ public function testSingleDefinitionProviderRespected() : void {
ConsumerClass
-
.annotated-container-cache
@@ -616,7 +607,6 @@ public function testSingleParameterStoreRespected() : void {
MyParameterStoreClass
-
.annotated-container-cache
@@ -653,7 +643,6 @@ public function testMultipleParameterStoresRespected() : void {
MyParameterStoreClassOne
MyParameterStoreClassTwo
-
.annotated-container-cache
@@ -661,78 +650,6 @@ public function testMultipleParameterStoresRespected() : void {
self::assertStringEqualsFile('vfs://root/annotated-container.xml', $expected);
}
- public function testSingleObserverRespected() : void {
- VirtualFilesystem::newFile('composer.json')
- ->withContent(json_encode([
- 'autoload' => [
- 'psr-0' => [
- 'Namespace\\' => 'src'
- ]
- ],
- ], JSON_THROW_ON_ERROR))->at($this->vfs);
-
- $input = new StubInput(['observer' => 'MyObserverClass'], ['init']);
- $exitCode = $this->subject->handle($input, $this->output);
-
- self::assertSame(0, $exitCode);
-
- $expected = <<
-
-
-
- src
-
-
-
-
-
- MyObserverClass
-
- .annotated-container-cache
-
-
-XML;
- self::assertStringEqualsFile('vfs://root/annotated-container.xml', $expected);
- }
-
- public function testMultipleObserversRespected() : void {
- VirtualFilesystem::newFile('composer.json')
- ->withContent(json_encode([
- 'autoload' => [
- 'psr-0' => [
- 'Namespace\\' => 'src'
- ]
- ],
- ], JSON_THROW_ON_ERROR))->at($this->vfs);
-
- $input = new StubInput(['observer' => ['MyObserverClassOne', 'MyObserverClassTwo']], ['init']);
- $exitCode = $this->subject->handle($input, $this->output);
-
- self::assertSame(0, $exitCode);
-
- $expected = <<
-
-
-
- src
-
-
-
-
-
- MyObserverClassOne
- MyObserverClassTwo
-
- .annotated-container-cache
-
-
-XML;
- self::assertStringEqualsFile('vfs://root/annotated-container.xml', $expected);
- }
-
-
public function testConfigFileBooleanThrowsException() : void {
$this->expectException(InvalidOptionType::class);
$this->expectExceptionMessage('The option "config-file" MUST NOT be a flag-only option.');
diff --git a/test/Unit/ContainerFactoryTestCase.php b/test/Unit/ContainerFactoryTestCase.php
index abc42b55..82f1cfea 100644
--- a/test/Unit/ContainerFactoryTestCase.php
+++ b/test/Unit/ContainerFactoryTestCase.php
@@ -5,6 +5,8 @@
use Cspray\AnnotatedContainer\Autowire\AutowireableFactory;
use Cspray\AnnotatedContainer\Autowire\AutowireableInvoker;
use Cspray\AnnotatedContainer\ContainerFactory\IlluminateContainerFactory;
+use Cspray\AnnotatedContainer\Event\Emitter;
+use Cspray\AnnotatedContainer\Event\Listener\ContainerFactory\BeforeContainerCreation;
use Cspray\AnnotatedContainer\Exception\InvalidAlias;
use Cspray\AnnotatedContainer\Profiles;
use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalyzer;
@@ -21,6 +23,7 @@
use Cspray\AnnotatedContainer\Exception\ParameterStoreNotFound;
use Cspray\AnnotatedContainer\Serializer\ContainerDefinitionSerializer;
use Cspray\AnnotatedContainer\AnnotatedContainer;
+use Cspray\AnnotatedContainer\Unit\Helper\StubContainerFactoryListener;
use Cspray\AnnotatedContainerFixture;
use Cspray\AnnotatedContainerFixture\Fixture;
use Cspray\AnnotatedContainerFixture\Fixtures;
@@ -43,7 +46,7 @@ abstract class ContainerFactoryTestCase extends TestCase {
private Profiles $activeProfiles;
- abstract protected function getContainerFactory() : ContainerFactory;
+ abstract protected function getContainerFactory(Emitter $emitter = new Emitter()) : ContainerFactory;
abstract protected function getBackingContainerInstanceOf() : ObjectType;
@@ -58,13 +61,14 @@ private function getContainer(
string $dir,
Profiles $profiles = null,
ParameterStore $parameterStore = null,
+ Emitter $emitter = new Emitter()
) : AnnotatedContainer {
$compiler = $this->getContainerDefinitionCompiler();
$optionsBuilder = ContainerDefinitionAnalysisOptionsBuilder::scanDirectories($dir);
$containerDefinition = $compiler->analyze($optionsBuilder->build());
$containerOptions = ContainerFactoryOptionsBuilder::forProfiles($profiles ?? Profiles::fromList(['default']));
- $factory = $this->getContainerFactory();
+ $factory = $this->getContainerFactory($emitter);
if ($parameterStore !== null) {
$factory->addParameterStore($parameterStore);
}
@@ -462,4 +466,20 @@ public function testDeserializingContainerWithInjectAllowsServiceCreation(Fixtur
$assertions($containerFactory, $deserialize);
}
+ public function testContainerCreationEventsEmitted() : void {
+ $emitter = new Emitter();
+
+ $listener = new StubContainerFactoryListener();
+ $emitter->addBeforeContainerCreationListener($listener);
+ $emitter->addAfterContainerCreationListener($listener);
+
+ $this->getContainer(
+ Fixtures::singleConcreteService()->getPath(),
+ Profiles::fromList(['default']),
+ emitter: $emitter
+ );
+
+ self::assertSame(['BeforeContainerCreation', 'AfterContainerCreation'], $listener->getTriggeredEvents());
+ }
+
}
diff --git a/test/Unit/ContainerFactoryTests/AurynContainerFactoryTest.php b/test/Unit/ContainerFactoryTests/AurynContainerFactoryTest.php
index 4985bb5f..a4ead4f8 100644
--- a/test/Unit/ContainerFactoryTests/AurynContainerFactoryTest.php
+++ b/test/Unit/ContainerFactoryTests/AurynContainerFactoryTest.php
@@ -5,14 +5,15 @@
use Auryn\Injector;
use Cspray\AnnotatedContainer\ContainerFactory\AurynContainerFactory;
use Cspray\AnnotatedContainer\ContainerFactory\ContainerFactory;
+use Cspray\AnnotatedContainer\Event\Emitter;
use Cspray\AnnotatedContainer\Unit\ContainerFactoryTestCase;
use Cspray\Typiphy\ObjectType;
use function Cspray\Typiphy\objectType;
class AurynContainerFactoryTest extends ContainerFactoryTestCase {
- protected function getContainerFactory() : ContainerFactory {
- return new AurynContainerFactory();
+ protected function getContainerFactory(Emitter $emitter = new Emitter()) : ContainerFactory {
+ return new AurynContainerFactory(emitter: $emitter);
}
protected function getBackingContainerInstanceOf() : ObjectType {
diff --git a/test/Unit/ContainerFactoryTests/IlluminateContainerFactoryTest.php b/test/Unit/ContainerFactoryTests/IlluminateContainerFactoryTest.php
index ca7c033a..f7d2693c 100644
--- a/test/Unit/ContainerFactoryTests/IlluminateContainerFactoryTest.php
+++ b/test/Unit/ContainerFactoryTests/IlluminateContainerFactoryTest.php
@@ -4,6 +4,7 @@
use Cspray\AnnotatedContainer\ContainerFactory\ContainerFactory;
use Cspray\AnnotatedContainer\ContainerFactory\IlluminateContainerFactory;
+use Cspray\AnnotatedContainer\Event\Emitter;
use Cspray\AnnotatedContainer\Unit\ContainerFactoryTestCase;
use Cspray\Typiphy\ObjectType;
use Illuminate\Contracts\Container\Container;
@@ -11,8 +12,8 @@
class IlluminateContainerFactoryTest extends ContainerFactoryTestCase {
- protected function getContainerFactory() : ContainerFactory {
- return new IlluminateContainerFactory();
+ protected function getContainerFactory(Emitter $emitter = new Emitter()) : ContainerFactory {
+ return new IlluminateContainerFactory(emitter: $emitter);
}
protected function getBackingContainerInstanceOf() : ObjectType {
diff --git a/test/Unit/ContainerFactoryTests/PhpDiContainerFactoryTest.php b/test/Unit/ContainerFactoryTests/PhpDiContainerFactoryTest.php
index 44633ed4..8594413e 100644
--- a/test/Unit/ContainerFactoryTests/PhpDiContainerFactoryTest.php
+++ b/test/Unit/ContainerFactoryTests/PhpDiContainerFactoryTest.php
@@ -4,6 +4,7 @@
use Cspray\AnnotatedContainer\ContainerFactory\ContainerFactory;
use Cspray\AnnotatedContainer\ContainerFactory\PhpDiContainerFactory;
+use Cspray\AnnotatedContainer\Event\Emitter;
use Cspray\AnnotatedContainer\Unit\ContainerFactoryTestCase;
use Cspray\Typiphy\ObjectType;
use DI\Container;
@@ -11,8 +12,8 @@
class PhpDiContainerFactoryTest extends ContainerFactoryTestCase {
- protected function getContainerFactory() : ContainerFactory {
- return new PhpDiContainerFactory();
+ protected function getContainerFactory(Emitter $emitter = new Emitter()) : ContainerFactory {
+ return new PhpDiContainerFactory(emitter: $emitter);
}
protected function getBackingContainerInstanceOf() : ObjectType {
diff --git a/test/Unit/Helper/StubContainerFactoryListener.php b/test/Unit/Helper/StubContainerFactoryListener.php
new file mode 100644
index 00000000..f34c7840
--- /dev/null
+++ b/test/Unit/Helper/StubContainerFactoryListener.php
@@ -0,0 +1,26 @@
+triggeredEvents[] = 'AfterContainerCreation';
+ }
+
+ public function handleBeforeContainerCreation(Profiles $profiles, ContainerDefinition $containerDefinition) : void {
+ $this->triggeredEvents[] = 'BeforeContainerCreation';
+ }
+
+ public function getTriggeredEvents() : array {
+ return $this->triggeredEvents;
+ }
+}
\ No newline at end of file
diff --git a/test/Unit/XmlBootstrappingConfigurationTest.php b/test/Unit/XmlBootstrappingConfigurationTest.php
index 07999da3..29b50b3c 100644
--- a/test/Unit/XmlBootstrappingConfigurationTest.php
+++ b/test/Unit/XmlBootstrappingConfigurationTest.php
@@ -393,104 +393,6 @@ public function createProvider(string $identifier) : DefinitionProvider {
self::assertContainsOnlyInstancesOf(StubDefinitionProviderWithDependencies::class, $provider->getDefinitionProviders());
}
- public function testObserversContainsNonClassThrowsException() : void {
- $badXml = <<
-
-
-
- src
-
-
-
- something not a class
-
-
-XML;
-
- VirtualFilesystem::newFile('annotated-container.xml')
- ->withContent($badXml)
- ->at($this->vfs);
-
- $this->expectException(InvalidBootstrapConfiguration::class);
- $this->expectExceptionMessage(sprintf(
- 'The entry something not a class in observers does not implement one of the following interfaces %s, %s, %s or %s',
- PreAnalysisObserver::class,
- PostAnalysisObserver::class,
- ContainerCreatedObserver::class,
- ContainerAnalyticsObserver::class
- ));
- new XmlBootstrappingConfiguration(
- 'vfs://root/annotated-container.xml',
- );
- }
-
- public function testObserversContainsNotObserverThrowsException() : void {
- $badXml = <<
-
-
-
- src
-
-
-
- Cspray\AnnotatedContainer\Helper\StubDefinitionProvider
-
-
-XML;
-
- VirtualFilesystem::newFile('annotated-container.xml')
- ->withContent($badXml)
- ->at($this->vfs);
-
- $this->expectException(InvalidBootstrapConfiguration::class);
- $this->expectExceptionMessage(sprintf(
- 'The entry Cspray\AnnotatedContainer\Helper\StubDefinitionProvider in observers does not implement one of the following interfaces %s, %s, %s or %s',
- PreAnalysisObserver::class,
- PostAnalysisObserver::class,
- ContainerCreatedObserver::class,
- ContainerAnalyticsObserver::class
- ));
- new XmlBootstrappingConfiguration(
- 'vfs://root/annotated-container.xml',
- );
- }
-
- public function testObserverFactoryPresentRespected() : void {
- $goodXml = <<
-
-
-
- src
-
-
-
- Cspray\AnnotatedContainer\Unit\Helper\StubBootstrapObserverWithDependencies
-
-
-XML;
-
- $observerFactory = new class implements ObserverFactory {
- public function createObserver(string $observer) : PreAnalysisObserver|PostAnalysisObserver|ContainerCreatedObserver {
- return new $observer('from observer factory');
- }
- };
-
- VirtualFilesystem::newFile('annotated-container.xml')
- ->withContent($goodXml)
- ->at($this->vfs);
-
- $config = new XmlBootstrappingConfiguration(
- 'vfs://root/annotated-container.xml',
- observerFactory: $observerFactory
- );
-
- self::assertCount(1, $config->getObservers());
- self::assertInstanceOf(StubBootstrapObserverWithDependencies::class, $config->getObservers()[0]);
- }
-
public function testVendorScanDirectoriesIncludedInList() : void {
$goodXml = <<