From ac086273f7b5f91728c45613cae751adac4af546 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 24 Mar 2024 16:07:59 +0100 Subject: [PATCH] allow to use enums as a service name --- CHANGELOG.md | 6 +++ composer.json | 2 +- docs/services.md | 63 +++++++++++++++++++++++++----- src/Application.php | 9 +++-- src/Application/Async/Http.php | 3 +- src/Application/Cli.php | 3 +- src/Application/Http.php | 3 +- src/Application/Implementation.php | 9 +++-- 8 files changed, 78 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba29bd6..f1f46c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [Unreleased] + +### Added + +- Support for using enums as a service name + ## 2.1.0 - 2024-03-10 ### Added diff --git a/composer.json b/composer.json index d467a66..12aea65 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "innmind/operating-system": "~4.1|~5.0", "innmind/cli": "^3.1", "innmind/immutable": "~5.2", - "innmind/di": "^2.0", + "innmind/di": "~2.1", "ramsey/uuid": "^4.7", "innmind/url": "^4.1", "innmind/filesystem": "~7.0", diff --git a/docs/services.md b/docs/services.md index 6da826c..5332718 100644 --- a/docs/services.md +++ b/docs/services.md @@ -2,11 +2,54 @@ For both [HTTP](http.md) and [CLI](cli.md) applications a service is an object referenced by a name in a [`Container`](https://github.com/Innmind/DI). -> [!NOTE] -> since a container only deals with objects Psalm will complain of type mismatches, so you'll have to suppress those errors (for now). - ## Defining a service +```php +use Innmind\DI\Service; +use Innmind\AMQP\Client; + +/** + * @template S of object + * @implements Service + */ +enum Services implements Service +{ + case amqpClient; + case producerClient; + case consumerClient; + + /** + * @return self + */ + public static function amqpClient(): self + { + /** @var self */ + return self::amqpClient; + } + + /** + * @return self + */ + public static function producerClient(): self + { + /** @var self */ + return self::producerClient; + } + + /** + * @return self + */ + public static function consumerClient(): self + { + /** @var self */ + return self::consumerClient; + } +} +``` + +> [!TIP] +> If you publish a package you can add an `@internal` flag on the static methods to tell your users to not use the service. And when you plan to remove a service you can use the `@deprecated` flag. + ```php use Innmind\Framework\{ Main\Http, @@ -23,7 +66,7 @@ new class extends Http|Cli { protected function configure(Application $app): Application { return $app->service( - 'amqp-client', + Services::amqpClient, static fn($_, OperatingSystem $os) => Factory::of($os)->make( Transport::tcp(), Url::of('amqp://guest:guest@localhost:5672/'), @@ -34,7 +77,7 @@ new class extends Http|Cli { }; ``` -This example defines a single service named `amqp-client` that relies on the `OperatingSystem` in order to work. +This example defines a single service named `amqpClient` that relies on the `OperatingSystem` in order to work. > [!NOTE] > this example uses [`innmind/amqp`](https://github.com/innmind/amqp) @@ -60,7 +103,7 @@ new class extends Http|Cli { protected function configure(Application $app): Application { return $app->service( - 'amqp-client', + Services::amqpClient, static fn($_, OperatingSystem $os, Environment $env) => Factory::of($os)->make( Transport::tcp(), Url::of($env->get('AMQP_URL')), // this will throw if the variable is not defined @@ -98,12 +141,12 @@ new class extends Http|Cli { { return $app ->service( - 'producer-client', + Services::producerClient, static fn($_, OperatingSystem $os) => Factory::of($os)->make(/* like above */), ) ->service( - 'consumer-client', - static fn(Container $container) => $container('producer-client')->with( + Services::consumerClient, + static fn(Container $container) => $container(Services::producerClient)->with( Qos::of(10), // prefetch 10 messages ), ); @@ -111,4 +154,4 @@ new class extends Http|Cli { }; ``` -Now every other service that relies on `consumer-client` will always have a configuration to prefetch 10 messages. +Now every other service that relies on `consumerClient` will always have a configuration to prefetch 10 messages. diff --git a/src/Application.php b/src/Application.php index 68f996f..db233d1 100644 --- a/src/Application.php +++ b/src/Application.php @@ -12,7 +12,10 @@ Environment as CliEnv, Command, }; -use Innmind\DI\Container; +use Innmind\DI\{ + Container, + Service, +}; use Innmind\Http\{ ServerRequest, Response, @@ -107,12 +110,12 @@ public function map(Middleware $map): self /** * @psalm-mutation-free * - * @param non-empty-string $name + * @param non-empty-string|Service $name * @param callable(Container, OperatingSystem, Environment): object $definition * * @return self */ - public function service(string $name, callable $definition): self + public function service(string|Service $name, callable $definition): self { return new self($this->app->service($name, $definition)); } diff --git a/src/Application/Async/Http.php b/src/Application/Async/Http.php index 2b6643b..583bc73 100644 --- a/src/Application/Async/Http.php +++ b/src/Application/Async/Http.php @@ -19,6 +19,7 @@ use Innmind\DI\{ Container, Builder, + Service, }; use Innmind\Http\{ ServerRequest, @@ -137,7 +138,7 @@ function(OperatingSystem $os, Environment $env) use ($map): array { /** * @psalm-mutation-free */ - public function service(string $name, callable $definition): self + public function service(string|Service $name, callable $definition): self { return new self( $this->os, diff --git a/src/Application/Cli.php b/src/Application/Cli.php index a074d60..f2b1825 100644 --- a/src/Application/Cli.php +++ b/src/Application/Cli.php @@ -16,6 +16,7 @@ use Innmind\DI\{ Builder, Container, + Service, }; use Innmind\Immutable\{ Sequence, @@ -106,7 +107,7 @@ public function mapOperatingSystem(callable $map): self /** * @psalm-mutation-free */ - public function service(string $name, callable $definition): self + public function service(string|Service $name, callable $definition): self { return new self( $this->os, diff --git a/src/Application/Http.php b/src/Application/Http.php index 6941d73..3a2f86f 100644 --- a/src/Application/Http.php +++ b/src/Application/Http.php @@ -13,6 +13,7 @@ use Innmind\DI\{ Container, Builder, + Service, }; use Innmind\Http\{ ServerRequest, @@ -118,7 +119,7 @@ public function mapOperatingSystem(callable $map): self /** * @psalm-mutation-free */ - public function service(string $name, callable $definition): self + public function service(string|Service $name, callable $definition): self { return new self( $this->os, diff --git a/src/Application/Implementation.php b/src/Application/Implementation.php index 77566e9..fc5a313 100644 --- a/src/Application/Implementation.php +++ b/src/Application/Implementation.php @@ -13,7 +13,10 @@ Environment as CliEnv, Command, }; -use Innmind\DI\Container; +use Innmind\DI\{ + Container, + Service, +}; use Innmind\Http\{ ServerRequest, Response, @@ -48,12 +51,12 @@ public function mapOperatingSystem(callable $map): self; /** * @psalm-mutation-free * - * @param non-empty-string $name + * @param non-empty-string|Service $name * @param callable(Container, OperatingSystem, Environment): object $definition * * @return self */ - public function service(string $name, callable $definition): self; + public function service(string|Service $name, callable $definition): self; /** * @psalm-mutation-free