@@ -1294,6 +1294,130 @@ the closure::
1294
1294
// services depending on which environment you're on
1295
1295
};
1296
1296
1297
+ Generating Adapters for Functional Interfaces
1298
+ ---------------------------------------------
1299
+
1300
+ Functional interfaces are interfaces with a single method.
1301
+ They are conceptually very similar to a closure except that their only method
1302
+ has a name. Moreover, they can be used as type-hints across your code.
1303
+
1304
+ The :class: `Symfony\\ Component\\ DependencyInjection\\ Attribute\\ AutowireCallable `
1305
+ attribute can be used to generate an adapter for a functional interface.
1306
+ Let's say you have the following functional interface::
1307
+
1308
+ // src/Service/MessageFormatterInterface.php
1309
+ namespace App\Service;
1310
+
1311
+ interface MessageFormatterInterface
1312
+ {
1313
+ public function format(string $message, array $parameters): string;
1314
+ }
1315
+
1316
+ Now, you can define a service implementing this method, among other util ones::
1317
+
1318
+ // src/Service/MessageFormatterInterface.php
1319
+ namespace App\Service;
1320
+
1321
+ class MessageUtils
1322
+ {
1323
+ // other utils methods...
1324
+
1325
+ public function format($string $message, array $parameters): string
1326
+ {
1327
+ // ...
1328
+ }
1329
+ }
1330
+
1331
+ We can now use ``#[AutowireCallable] `` with our ``MessageUtils `` service
1332
+ to inject our functional interface implementation::
1333
+
1334
+ namespace App\Service\Mail;
1335
+
1336
+ use App\Service\MessageFormatterInterface;
1337
+ use App\Service\MessageUtils;
1338
+ use Symfony\Component\DependencyInjection\Attribute\AutowireCallable;
1339
+
1340
+ class Mailer
1341
+ {
1342
+ public function __construct(
1343
+ #[AutowireCallable(service: MessageUtils::class, method: 'formatMessage')]
1344
+ private MessageFormatterInterface $formatter
1345
+ ) {
1346
+ }
1347
+
1348
+ public function sendMail($string $message, array $parameters): string
1349
+ {
1350
+ $formattedMessage = $this->formatter->format($message, $parameters);
1351
+
1352
+ // ...
1353
+ }
1354
+ }
1355
+
1356
+ .. versionadded :: 6.3
1357
+
1358
+ The :class: `Symfony\\ Component\\ DependencyInjection\\ Attribute\\ AutowireCallable `
1359
+ attribute was introduced in Symfony 6.3.
1360
+
1361
+ Alternatively, generating an adapter for a functional interface can also
1362
+ be done through configuration:
1363
+
1364
+ .. configuration-block ::
1365
+
1366
+ .. code-block :: yaml
1367
+
1368
+ # config/services.yaml
1369
+ services :
1370
+
1371
+ # ...
1372
+
1373
+ app.message_formatter :
1374
+ class : App\Service\MessageFormatterInterface
1375
+ from_callable : [!service {class: 'App\Service\MessageUtils'}, 'formatMessage']
1376
+
1377
+ .. code-block :: xml
1378
+
1379
+ <!-- config/services.xml -->
1380
+ <?xml version =" 1.0" encoding =" UTF-8" ?>
1381
+ <container xmlns =" http://symfony.com/schema/dic/services"
1382
+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
1383
+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
1384
+ https://symfony.com/schema/dic/services/services-1.0.xsd" >
1385
+
1386
+ <services >
1387
+ <!-- ... -->
1388
+
1389
+ <service id =" app.message_formatter" class =" App\Service\MessageFormatterInterface" >
1390
+ <from-callable method =" formatMessage" >
1391
+ <service class =" App\Service\MessageUtils" />
1392
+ </from-callable >
1393
+ </service >
1394
+
1395
+ </services >
1396
+ </container >
1397
+
1398
+ .. code-block :: php
1399
+
1400
+ // config/services.php
1401
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1402
+
1403
+ use App\Service\MessageFormatterInterface;
1404
+ use App\Service\MessageUtils;
1405
+
1406
+ return function(ContainerConfigurator $container) {
1407
+ // ...
1408
+
1409
+ $container
1410
+ ->set('app.message_formatter', MessageFormatterInterface::class)
1411
+ ->fromCallable([inline_service(MessageUtils::class), 'formatMessage'])
1412
+ ->alias(MessageFormatterInterface::class, 'app.message_formatter')
1413
+ ;
1414
+ };
1415
+
1416
+ By doing so, Symfony will generate a class (also called an *adapter *)
1417
+ implementing ``MessageFormatterInterface `` that will forward calls of
1418
+ ``MessageFormatterInterface::format() `` to your underlying service's method
1419
+ ``MessageUtils::format() ``, with all its arguments.
1420
+
1297
1421
Learn more
1298
1422
----------
1299
1423
0 commit comments