跳到內容

如何使用服務定義物件

編輯此頁面

服務定義是描述容器應如何建構服務的指示。它們不是您的應用程式使用的實際服務。容器將根據定義中的組態建立實際的類別實例。

通常,您會使用 YAML、XML 或 PHP 來描述服務定義。但是,如果您正在使用服務容器執行進階操作,例如使用 編譯器通道 或建立 依賴注入擴充功能,您可能需要直接使用定義服務將如何實例化的 Definition 物件。

取得和設定服務定義

有一些有用的方法可以用於處理服務定義

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use Symfony\Component\DependencyInjection\Definition;

// finds out if there is an "app.mailer" definition
$container->hasDefinition('app.mailer');
// finds out if there is an "app.mailer" definition or alias
$container->has('app.mailer');

// gets the "app.user_config_manager" definition
$definition = $container->getDefinition('app.user_config_manager');
// gets the definition with the "app.user_config_manager" ID or alias
$definition = $container->findDefinition('app.user_config_manager');

// adds a new "app.number_generator" definition
$definition = new Definition(\App\NumberGenerator::class);
$container->setDefinition('app.number_generator', $definition);

// shortcut for the previous method
$container->register('app.number_generator', \App\NumberGenerator::class);

使用定義

建立新的定義

除了操作和檢索現有的定義之外,您還可以透過 Definition 類別定義新的服務定義。

類別

Definition 類別的第一個可選參數是從容器中提取服務時傳回的物件的完整類別名稱

1
2
3
4
5
6
7
8
9
10
11
use App\Config\CustomConfigManager;
use App\Config\UserConfigManager;
use Symfony\Component\DependencyInjection\Definition;

$definition = new Definition(UserConfigManager::class);

// override the class
$definition->setClass(CustomConfigManager::class);

// get the class configured for this definition
$class = $definition->getClass();

建構子參數

Definition 類別的第二個可選參數是一個陣列,其中包含在從容器中提取服務時傳回的物件的建構子中傳遞的參數

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
use App\Config\DoctrineConfigManager;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

$definition = new Definition(DoctrineConfigManager::class, [
    new Reference('doctrine'), // a reference to another service
    '%app.config_table_name%',  // will be resolved to the value of a container parameter
]);

// gets all arguments configured for this definition
$constructorArguments = $definition->getArguments();

// gets a specific argument
$firstArgument = $definition->getArgument(0);

// adds a new named argument
// '$argumentName' = the name of the argument in the constructor, including the '$' symbol
$definition = $definition->setArgument('$argumentName', $argumentValue);

// adds a new argument
$definition->addArgument($argumentValue);

// replaces argument on a specific index (0 = first argument)
$definition->replaceArgument($index, $argument);

// replaces all previously configured arguments with the passed array
$definition->setArguments($arguments);

警告

不要使用 get() 來取得您想要作為建構子參數注入的服務,因為該服務尚不可用。請改為使用如上所示的 Reference 實例。

方法呼叫

如果您正在使用的服務使用 setter 注入,那麼您也可以操作定義中的任何方法呼叫

1
2
3
4
5
6
7
8
9
10
11
// gets all configured method calls
$methodCalls = $definition->getMethodCalls();

// configures a new method call
$definition->addMethodCall('setLogger', [new Reference('logger')]);

// configures an immutable-setter
$definition->addMethodCall('withLogger', [new Reference('logger')], true);

// replaces all previously configured method calls with the passed array
$definition->setMethodCalls($methodCalls);

提示

在服務容器文章的 PHP 程式碼區塊中,有更多關於使用定義的特定方式的範例,例如使用 Factory 建立服務如何使用父服務管理常見依賴項

注意

此處變更服務定義的方法只能在容器編譯之前使用。一旦容器編譯完成,您就無法進一步操作服務定義。若要深入瞭解編譯容器,請參閱編譯容器

要求檔案

在某些情況下,您可能需要在服務本身載入之前包含另一個檔案。若要執行此操作,您可以使用 setFile() 方法

1
$definition->setFile('/src/path/to/file/foo.php');

請注意,Symfony 會在內部呼叫 PHP 陳述式 require_once,這表示您的檔案在每個請求中只會包含一次。

本作品,包括程式碼範例,根據 Creative Commons BY-SA 3.0 授權條款授權。
目錄
    版本