Skip to content

Commit acd8c2b

Browse files
authored
Add class level docs (#21)
1 parent 977051a commit acd8c2b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+483
-72
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ class FooImplementation {}
4242

4343
// app bootstrap in __DIR__ . '/app.php'
4444

45-
use Cspray\AnnotatedContainer\AurynInjectorFactory;
45+
use Cspray\AnnotatedContainer\AurynContainerFactory;
4646
use Cspray\AnnotatedContainer\PhpParserInjectorDefinitionCompiler;
4747

4848
$compiler = new PhpParserInjectorDefinitionCompiler();
4949
$injectorDefinition = $compiler->compileDirectory('env_identifier', __DIR__ . '/src');
50-
$injector = (new AurynInjectorFactory)->createContainer($injectorDefinition);
50+
$injector = (new AurynContainerFactory)->createContainer($injectorDefinition);
5151

5252
var_dump($injector->make(Foo::class));
5353
```

examples/getting_started/dev_app.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
$compiler = new \Cspray\AnnotatedContainer\PhpParserContainerDefinitionCompiler();
66
$injectorDefinition = $compiler->compile('dev', __DIR__ . '/src');
7-
$injector = (new Cspray\AnnotatedContainer\AurynInjectorFactory)->createInjector($injectorDefinition);
7+
$injector = (new Cspray\AnnotatedContainer\AurynContainerFactory)->createInjector($injectorDefinition);
88

99
$blobStorage = $injector->make(\Acme\AnnotatedContainerDemo\BlobStorage::class);
1010

examples/getting_started/prod_app.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
$compiler = new \Cspray\AnnotatedContainer\PhpParserContainerDefinitionCompiler();
66
$injectorDefinition = $compiler->compile('prod', __DIR__ . '/src');
7-
$injector = (new Cspray\AnnotatedContainer\AurynInjectorFactory)->createInjector($injectorDefinition);
7+
$injector = (new Cspray\AnnotatedContainer\AurynContainerFactory)->createInjector($injectorDefinition);
88

99
$blobStorage = $injector->make(\Acme\AnnotatedContainerDemo\BlobStorage::class);
1010

examples/getting_started/test_app.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
$compiler = new \Cspray\AnnotatedContainer\PhpParserContainerDefinitionCompiler();
66
$injectorDefinition = $compiler->compile('test', __DIR__ . '/src');
7-
$injector = (new Cspray\AnnotatedContainer\AurynInjectorFactory)->createInjector($injectorDefinition);
7+
$injector = (new Cspray\AnnotatedContainer\AurynContainerFactory)->createInjector($injectorDefinition);
88

99
$blobStorage = $injector->make(\Acme\AnnotatedContainerDemo\BlobStorage::class);
1010

examples/scalar_and_service_defines/constructor_injection_app.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
$compiler = new \Cspray\AnnotatedContainer\PhpParserInjectorDefinitionCompiler();
66
$injectorDefinition = $compiler->compileDirectory('dev', __DIR__ . '/src');
7-
$injector = (new Cspray\AnnotatedContainer\AurynInjectorFactory)->createContainer($injectorDefinition);
7+
$injector = (new Cspray\AnnotatedContainer\AurynContainerFactory)->createContainer($injectorDefinition);
88

99
$subject = $injector->make(\Acme\AnnotatedContainerDemo\MixedDefinesConstructorInjection::class);
1010

examples/scalar_and_service_defines/prepare_injection_app.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
$compiler = new \Cspray\AnnotatedContainer\PhpParserContainerDefinitionCompiler();
66
$injectorDefinition = $compiler->compile('dev', __DIR__ . '/src');
7-
$injector = (new Cspray\AnnotatedContainer\AurynInjectorFactory)->createInjector($injectorDefinition);
7+
$injector = (new Cspray\AnnotatedContainer\AurynContainerFactory)->createInjector($injectorDefinition);
88

99
$subject = $injector->make(\Acme\AnnotatedContainerDemo\MixedDefinesSetterInjection::class);
1010

examples/scalar_values/dev_app.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
$compiler = new \Cspray\AnnotatedContainer\PhpParserInjectorDefinitionCompiler();
66
$injectorDefinition = $compiler->compileDirectory('dev', __DIR__ . '/src');
7-
$injector = (new Cspray\AnnotatedContainer\AurynInjectorFactory)->createContainer($injectorDefinition);
7+
$injector = (new Cspray\AnnotatedContainer\AurynContainerFactory)->createContainer($injectorDefinition);
88

99
$scalarGetter = $injector->make(\Acme\AnnotatedContainerDemo\ScalarGetter::class);
1010

examples/scalar_values/prod_app.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
$compiler = new \Cspray\AnnotatedContainer\PhpParserInjectorDefinitionCompiler();
66
$injectorDefinition = $compiler->compileDirectory('prod', __DIR__ . '/src');
7-
$injector = (new Cspray\AnnotatedContainer\AurynInjectorFactory)->createContainer($injectorDefinition);
7+
$injector = (new Cspray\AnnotatedContainer\AurynContainerFactory)->createContainer($injectorDefinition);
88

99
$scalarGetter = $injector->make(\Acme\AnnotatedContainerDemo\ScalarGetter::class);
1010

examples/scalar_values/test_app.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
$compiler = new \Cspray\AnnotatedContainer\PhpParserInjectorDefinitionCompiler();
66
$injectorDefinition = $compiler->compileDirectory('test', __DIR__ . '/src');
7-
$injector = (new Cspray\AnnotatedContainer\AurynInjectorFactory)->createContainer($injectorDefinition);
7+
$injector = (new Cspray\AnnotatedContainer\AurynContainerFactory)->createContainer($injectorDefinition);
88

99
$scalarGetter = $injector->make(\Acme\AnnotatedContainerDemo\ScalarGetter::class);
1010

src/AliasDefinition.php

+18-2
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,32 @@
33
namespace Cspray\AnnotatedContainer;
44

55
/**
6-
* Defines the ServiceDefinition that should be used to generate aliases on the wired Injector.
6+
* Define the concrete Service that should be used when constructing an abstract Service.
77
*
8-
* @package Cspray\AnnotatedContainer
8+
* @see AliasDefinitionBuilder
99
*/
1010
interface AliasDefinition {
1111

12+
/**
13+
* An abstract Service used by your application but cannot be constructed directly.
14+
*
15+
* @return ServiceDefinition
16+
*/
1217
public function getAbstractService() : ServiceDefinition;
1318

19+
/**
20+
* The concrete Service that should be used where your applications requires the corresponding abstract Service.
21+
*
22+
* @return ServiceDefinition
23+
*/
1424
public function getConcreteService() : ServiceDefinition;
1525

26+
/**
27+
* Returns whether the given $aliasDefinition has matching abstract and concrete services.
28+
*
29+
* @param AliasDefinition $aliasDefinition
30+
* @return bool
31+
*/
1632
public function equals(AliasDefinition $aliasDefinition) : bool;
1733

1834
}

src/AliasDefinitionBuilder.php

+24
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,23 @@
44

55
use Cspray\AnnotatedContainer\Exception\DefinitionBuilderException;
66

7+
/**
8+
* The preferred method for constructing AliasDefinition instances.
9+
*/
710
final class AliasDefinitionBuilder {
811

912
private ServiceDefinition $abstractType;
1013
private ServiceDefinition $concreteType;
1114

1215
private function __construct() {}
1316

17+
/**
18+
* Define the abstract Service that should have an alias defined for it.
19+
*
20+
* @param ServiceDefinition $serviceDefinition
21+
* @return static
22+
* @throws DefinitionBuilderException
23+
*/
1424
public static function forAbstract(ServiceDefinition $serviceDefinition) : self {
1525
if (!$serviceDefinition->isAbstract()) {
1626
throw new DefinitionBuilderException(sprintf(
@@ -23,6 +33,15 @@ public static function forAbstract(ServiceDefinition $serviceDefinition) : self
2333
return $instance;
2434
}
2535

36+
/**
37+
* Define the concrete Service that acts as an alias for the given abstract Service.
38+
*
39+
* This method is immutable and a new AliasDefinitionBuilder will be returned.
40+
*
41+
* @param ServiceDefinition $serviceDefinition
42+
* @return $this
43+
* @throws DefinitionBuilderException
44+
*/
2645
public function withConcrete(ServiceDefinition $serviceDefinition) : self {
2746
if ($serviceDefinition->isAbstract()) {
2847
throw new DefinitionBuilderException(sprintf(
@@ -35,6 +54,11 @@ public function withConcrete(ServiceDefinition $serviceDefinition) : self {
3554
return $instance;
3655
}
3756

57+
/**
58+
* Returns an AliasDefinition with the provided abstract and concrete Services.
59+
*
60+
* @return AliasDefinition
61+
*/
3862
public function build() : AliasDefinition {
3963
return new class($this->abstractType, $this->concreteType) implements AliasDefinition {
4064
private ServiceDefinition $abstractService;

src/Attribute/InjectService.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
#[Attribute(Attribute::TARGET_PARAMETER)]
1414
final class InjectService {
1515

16-
public function __construct(
17-
private string $name
18-
) {}
16+
public function __construct(private string $name) {}
1917

2018
}

src/Attribute/ServiceDelegate.php

+1-9
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,6 @@
77
#[Attribute(Attribute::TARGET_METHOD)]
88
final class ServiceDelegate {
99

10-
private string $forService;
11-
12-
public function __construct(string $forService) {
13-
$this->forService = $forService;
14-
}
15-
16-
public function getForService() : string {
17-
return $this->forService;
18-
}
10+
public function __construct(private string $forService) {}
1911

2012
}

src/Attribute/ServiceProfile.php

+1-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@
77
#[Attribute(Attribute::TARGET_CLASS)]
88
final class ServiceProfile {
99

10-
private array $profiles;
1110

12-
public function __construct(array $profiles) {
13-
$this->profiles = $profiles;
14-
}
11+
public function __construct(private array $profiles) {}
1512

1613
}

src/AurynInjectorFactory.php src/AurynContainerFactory.php

+21-7
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,31 @@
55
use Auryn\InjectionException;
66
use Auryn\Injector;
77
use Cspray\AnnotatedContainer\Exception\ContainerException;
8-
use Psr\Container\ContainerExceptionInterface;
98
use Psr\Container\ContainerInterface;
10-
use Psr\Container\NotFoundExceptionInterface;
119

1210
/**
13-
* Wires together an Injector from an ContainerDefinition or a JSON serialization of an ContainerDefinition.
14-
*
15-
* @package Cspray\AnnotatedContainer
11+
* Creates a PSR Container from a ContainerDefinition backed by an Auryn\Injector.
1612
*/
17-
final class AurynInjectorFactory implements ContainerFactory {
18-
13+
final class AurynContainerFactory implements ContainerFactory {
14+
15+
/**
16+
* Returns a PSR ContainerInterface that uses an Auryn\Injector to create services.
17+
*
18+
* Because Auryn does not provide a PSR compatible Container we wrap the injector in an anonymous class that
19+
* implements the PSR ContainerInterface. Auryn has the capacity to recursively autowire Services at time of
20+
* construction and does not necessarily need to have the Service defined ahead of time if the constructor
21+
* dependencies can be reliably determined. This fact makes the has() method for this particular Container a little
22+
* tricky in that a service could be successfully constructed but if we don't have something specifically defined
23+
* stating how to construct some aspect of it we can't reliably determine whether or not the Container "has" the
24+
* Service.
25+
*
26+
* This limitation should be short-lived as the Auryn Injector is being migrated to a new organization and codebase.
27+
* Once that migration has been completed a new ContainerFactory using that implementation will be used and this
28+
* implementation will be deprecated.
29+
*
30+
* @param ContainerDefinition $containerDefinition
31+
* @return ContainerInterface
32+
*/
1933
public function createContainer(ContainerDefinition $containerDefinition) : ContainerInterface {
2034
return new class($this->createInjector($containerDefinition)) implements ContainerInterface {
2135

src/CacheAwareContainerDefinitionCompiler.php

+23-1
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,42 @@
33
namespace Cspray\AnnotatedContainer;
44

55
use Cspray\AnnotatedContainer\Exception\InvalidCacheException;
6-
use InvalidArgumentException;
76

7+
/**
8+
* A ContainerDefinitionCompiler decorator that allows for a ContainerDefinition to be serialized and cached to the
9+
* filesystem; this could potentially save time on very large codebases or be used when building production to not
10+
* require Container compilation on every request.
11+
*/
812
final class CacheAwareContainerDefinitionCompiler implements ContainerDefinitionCompiler {
913

1014
private ContainerDefinitionCompiler $containerDefinitionCompiler;
1115
private ContainerDefinitionSerializer $containerDefinitionSerializer;
1216
private string $cacheDir;
1317

18+
/**
19+
* @param ContainerDefinitionCompiler $containerDefinitionCompiler The compiler to use if the cache file is not present
20+
* @param ContainerDefinitionSerializer $containerDefinitionSerializer The serializer to serialize/deserialize the cached ContainerDefinition
21+
* @param string $cacheDir The directory that the cache files should be generated
22+
*/
1423
public function __construct(ContainerDefinitionCompiler $containerDefinitionCompiler, ContainerDefinitionSerializer $containerDefinitionSerializer, string $cacheDir) {
1524
$this->containerDefinitionCompiler = $containerDefinitionCompiler;
1625
$this->containerDefinitionSerializer = $containerDefinitionSerializer;
1726
$this->cacheDir = $cacheDir;
1827
}
1928

29+
/**
30+
* Will generate a ContainerDefinition from a serialized cache file.
31+
*
32+
* If the cached file is not present will generate a ContainerDefinition from the passed ContainerDefinitionCompiler
33+
* and save it to the $cacheDir based off of the directories to scan and the active profiles for the given compile
34+
* options.
35+
*
36+
* Please see bin/annotated-container compile --help for more information on pre-generating the cached ContainerDefinition.
37+
*
38+
* @param ContainerDefinitionCompileOptions $containerDefinitionCompileOptions
39+
* @return ContainerDefinition
40+
* @throws InvalidCacheException
41+
*/
2042
public function compile(ContainerDefinitionCompileOptions $containerDefinitionCompileOptions): ContainerDefinition {
2143
$cacheFile = $this->getCacheFile(
2244
$containerDefinitionCompileOptions->getProfiles(),

src/ContainerDefinition.php

+35-10
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,79 @@
22

33
namespace Cspray\AnnotatedContainer;
44

5+
use Cspray\AnnotatedContainer\Exception\ContainerDefinitionMergeException;
6+
57
/**
8+
* The heart of the AnnotatedContainer; the ContainerDefinition, an object which defines how a Container should be
9+
* configured.
610
*
7-
*
8-
* @package Cspray\AnnotatedContainer
11+
* @see ContainerDefinitionBuilder
912
*/
1013
interface ContainerDefinition {
1114

15+
/**
16+
* An immutable method that will return new ContainerDefinition that has the contents of this ContainerDefinition and
17+
* the passed $containerDefinition.
18+
*
19+
* @param ContainerDefinition $containerDefinition
20+
* @return ContainerDefinition
21+
* @throws ContainerDefinitionMergeException An exception that can be thrown if the given $containerDefinition can't be merged for some reason
22+
*/
1223
public function merge(ContainerDefinition $containerDefinition) : ContainerDefinition;
1324

1425
/**
15-
* Returns a set of ServiceDefinition that are shared with the Injector.
26+
* Return a set of ServiceDefinitions that this Container is aware of.
1627
*
1728
* Note that this IS NOT necessarily an exhaustive list of every class and interface annotated with Service. It is
18-
* possible, and likely, that a concrete implementation is listed as an alias or is not meant to be loaded with this
19-
* Injector due to the environment it is supposed to be running in.
29+
* possible, and likely, that a concrete implementation is marked as belonging to a profile that isn't currently
30+
* active. This, and potentially other valid reasons, might exclude a type annotated with Service from appearing
31+
* this collection.
2032
*
2133
* @return ServiceDefinition[]
2234
*/
2335
public function getServiceDefinitions() : array;
2436

2537
/**
26-
* Returns a set of AliasDefinition that define which concrete implementations are meant to be used for a given
27-
* interface.
38+
* Returns a set of AliasDefinition that define which concrete services are possible candidate for a given abstract
39+
* service.
2840
*
29-
* Please note that as of 0.1.x multiple alias conflict resolution is not in place and it is possible to have
30-
* multiple AliasDefinitions for the same interface that could result in unexpected services from being injected.
31-
* Multiple alias conflict resolution is scheduled for the 0.2.x release series.
41+
* Note that it is possible for an abstract service to have multiple AliasDefinition defined for it. It is not the
42+
* job of the ContainerDefinition to determine what should be done in this situation; it is meant to simply provide
43+
* the results of a configuration for a Container and an annotated configuration is possible to have multiple
44+
* concrete services that could satisfy an abstract service. It is the responsibility of the ContainerFactory
45+
* or a LogicalConstraintValidator to recognize multiple aliases are possible and take the appropriate steps.
3246
*
3347
* @return AliasDefinition[]
3448
*/
3549
public function getAliasDefinitions() : array;
3650

3751
/**
52+
* Returns a set of ServicePrepareDefinition that determine which service methods will be automatically invoked
53+
* after service construction.
54+
*
3855
* @return ServicePrepareDefinition[]
3956
*/
4057
public function getServicePrepareDefinitions() : array;
4158

4259
/**
60+
* Returns a set of InjectScalarDefinition that determine what values to use when a service parameter requires a
61+
* scalar or non-object value injected into it.
62+
*
4363
* @return InjectScalarDefinition[]
4464
*/
4565
public function getInjectScalarDefinitions() : array;
4666

4767
/**
68+
* Returns a set of InjectServiceDefinition that determine a specific service to inject into a parameter where
69+
* normal alias resolution might not be possible.
70+
*
4871
* @return InjectServiceDefinition[]
4972
*/
5073
public function getInjectServiceDefinitions() : array;
5174

5275
/**
76+
* Returns a set of ServiceDelegateDefinition that determine which services require factories to be constructed.
77+
*
5378
* @return ServiceDelegateDefinition[]
5479
*/
5580
public function getServiceDelegateDefinitions() : array;

0 commit comments

Comments
 (0)