@@ -1334,6 +1334,130 @@ the closure::
1334
1334
// services depending on which environment you're on
1335
1335
};
1336
1336
1337
+ Generating Adapters for Functional Interfaces
1338
+ ---------------------------------------------
1339
+
1340
+ Functional interfaces are interfaces with a single method.
1341
+ They are conceptually very similar to a closure except that their only method
1342
+ has a name. Moreover, they can be used as type-hints across your code.
1343
+
1344
+ The :class: `Symfony\\ Component\\ DependencyInjection\\ Attribute\\ AutowireCallable `
1345
+ attribute can be used to generate an adapter for a functional interface.
1346
+ Let's say you have the following functional interface::
1347
+
1348
+ // src/Service/MessageFormatterInterface.php
1349
+ namespace App\Service;
1350
+
1351
+ interface MessageFormatterInterface
1352
+ {
1353
+ public function format(string $message, array $parameters): string;
1354
+ }
1355
+
1356
+ Now, you can define a service implementing this method, among other util ones::
1357
+
1358
+ // src/Service/MessageFormatterInterface.php
1359
+ namespace App\Service;
1360
+
1361
+ class MessageUtils
1362
+ {
1363
+ // other utils methods...
1364
+
1365
+ public function format($string $message, array $parameters): string
1366
+ {
1367
+ // ...
1368
+ }
1369
+ }
1370
+
1371
+ We can now use ``#[AutowireCallable] `` with our ``MessageUtils `` service
1372
+ to inject our functional interface implementation::
1373
+
1374
+ namespace App\Service\Mail;
1375
+
1376
+ use App\Service\MessageFormatterInterface;
1377
+ use App\Service\MessageUtils;
1378
+ use Symfony\Component\DependencyInjection\Attribute\AutowireCallable;
1379
+
1380
+ class Mailer
1381
+ {
1382
+ public function __construct(
1383
+ #[AutowireCallable(service: MessageUtils::class, method: 'formatMessage')]
1384
+ private MessageFormatterInterface $formatter
1385
+ ) {
1386
+ }
1387
+
1388
+ public function sendMail($string $message, array $parameters): string
1389
+ {
1390
+ $formattedMessage = $this->formatter->format($message, $parameters);
1391
+
1392
+ // ...
1393
+ }
1394
+ }
1395
+
1396
+ .. versionadded :: 6.3
1397
+
1398
+ The :class: `Symfony\\ Component\\ DependencyInjection\\ Attribute\\ AutowireCallable `
1399
+ attribute was introduced in Symfony 6.3.
1400
+
1401
+ Alternatively, generating an adapter for a functional interface can also
1402
+ be done through configuration:
1403
+
1404
+ .. configuration-block ::
1405
+
1406
+ .. code-block :: yaml
1407
+
1408
+ # config/services.yaml
1409
+ services :
1410
+
1411
+ # ...
1412
+
1413
+ app.message_formatter :
1414
+ class : App\Service\MessageFormatterInterface
1415
+ from_callable : [!service {class: 'App\Service\MessageUtils'}, 'formatMessage']
1416
+
1417
+ .. code-block :: xml
1418
+
1419
+ <!-- config/services.xml -->
1420
+ <?xml version =" 1.0" encoding =" UTF-8" ?>
1421
+ <container xmlns =" http://symfony.com/schema/dic/services"
1422
+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
1423
+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
1424
+ https://symfony.com/schema/dic/services/services-1.0.xsd" >
1425
+
1426
+ <services >
1427
+ <!-- ... -->
1428
+
1429
+ <service id =" app.message_formatter" class =" App\Service\MessageFormatterInterface" >
1430
+ <from-callable method =" formatMessage" >
1431
+ <service class =" App\Service\MessageUtils" />
1432
+ </from-callable >
1433
+ </service >
1434
+
1435
+ </services >
1436
+ </container >
1437
+
1438
+ .. code-block :: php
1439
+
1440
+ // config/services.php
1441
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1442
+
1443
+ use App\Service\MessageFormatterInterface;
1444
+ use App\Service\MessageUtils;
1445
+
1446
+ return function(ContainerConfigurator $container) {
1447
+ // ...
1448
+
1449
+ $container
1450
+ ->set('app.message_formatter', MessageFormatterInterface::class)
1451
+ ->fromCallable([inline_service(MessageUtils::class), 'formatMessage'])
1452
+ ->alias(MessageFormatterInterface::class, 'app.message_formatter')
1453
+ ;
1454
+ };
1455
+
1456
+ By doing so, Symfony will generate a class (also called an *adapter *)
1457
+ implementing ``MessageFormatterInterface `` that will forward calls of
1458
+ ``MessageFormatterInterface::format() `` to your underlying service's method
1459
+ ``MessageUtils::format() ``, with all its arguments.
1460
+
1337
1461
Learn more
1338
1462
----------
1339
1463
0 commit comments