Skip to content
intermediate Phase 29 · DI Patterns

DI Arguments in di.xml

Passing configuration values through dependency injection using string, int, boolean, object, array, const, and null argument types.

45m
0 problems
Topic Progress 0%

String and Number Arguments

The simplest arguments in di.xml are scalar values—strings and numbers. These pass literal configuration values into constructor parameters.

String arguments:

<type name="Vendor\Module\Service\Logger">
    <arguments>
        <argument name="logFile" xsi:type="string">var/log/custom.log</argument>
        <argument name="channel" xsi:type="string">vendor_module</argument>
    </arguments>
</type>

Number arguments:

<type name="Vendor\Module\Service\Processor">
    <arguments>
        <argument name="batchSize" xsi:type="number">100</argument>
        <argument name="timeout" xsi:type="number">30.5</argument>
    </arguments>
</type>

How values resolve:

  • xsi:type="string" → PHP string
  • xsi:type="number" → PHP int or float (Magento determines automatically)
  • The constructor parameter type hint must accept the value

Practical example:

namespace Vendor\Module\Service;

class Processor
{
    public function __construct(
        private int $batchSize,
        private string $logFile
    ) {}
}
<type name="Vendor\Module\Service\Processor">
    <arguments>
        <argument name="batchSize" xsi:type="number">50</argument>
        <argument name="logFile" xsi:type="string">import.log</argument>
    </arguments>
</type>

Important: If no argument is configured in di.xml and no default value exists, the ObjectManager will attempt to resolve the dependency using type inference. Scalar types (string, int, float, bool) cannot be auto-resolved, so they must be explicitly configured or have default values.

Boolean and Null Arguments

Boolean and null arguments control feature flags and optional dependencies.

Boolean arguments:

<type name="Vendor\Module\Service\Exporter">
    <arguments>
        <argument name="debugMode" xsi:type="boolean">true</argument>
        <argument name="enableCompression" xsi:type="boolean">false</argument>
    </arguments>
</type>

Null arguments:

<type name="Vendor\Module\Service\Handler">
    <arguments>
        <argument name="fallbackHandler" xsi:type="object">null</argument>
    </arguments>
</type>

Null for optional dependencies:

namespace Vendor\Module\Service;

class Handler
{
    public function __construct(
        private \Psr\Log\LoggerInterface $logger,
        private ?\Vendor\Module\Handler\FallbackHandler $fallbackHandler = null
    ) {}
    
    public function handle(string $data): void
    {
        if ($this->fallbackHandler !== null) {
            $this->fallbackHandler->process($data);
        }
    }
}

When to use null:

  • Making an object dependency optional
  • Disabling a feature that normally requires an object
  • Overriding a preference to remove a dependency

Boolean use cases:

  • Feature flags within DI configuration
  • Toggling behaviors based on scope (frontend vs admin)
  • Conditional logic in constructor setup

Object Arguments

Object arguments inject specific class implementations or interface bindings into constructor parameters.

Basic object argument:

<type name="Vendor\Module\Service\NotificationService">
    <arguments>
        <argument name="sender" xsi:type="object">Vendor\Module\Email\SmtpSender</argument>
    </arguments>
</type>

Interface binding:

<type name="Vendor\Module\Service\NotificationService">
    <arguments>
        <argument name="sender" xsi:type="object">Vendor\Module\Email\SmsSender</argument>
    </arguments>
</type>
// Constructor expects interface
public function __construct(
    private \Vendor\Module\Email\SenderInterface $sender
) {}

Virtual type as argument:

<virtualType name="FileLogger" type="Magento\Framework\Logger\Monolog">
    <arguments>
        <argument name="name" xsi:type="string">custom.log</argument>
    </arguments>
</virtualType>

<type name="Vendor\Module\Service\Processor">
    <arguments>
        <argument name="logger" xsi:type="object">FileLogger</argument>
    </arguments>
</type>

Multiple objects in array:

<type name="Vendor\Module\Service\ChainProcessor">
    <arguments>
        <argument name="processors" xsi:type="array">
            <item name="0" xsi:type="object">Vendor\Module\Processor\Validation</item>
            <item name="1" xsi:type="object">Vendor\Module\Processor\Transformation</item>
            <item name="2" xsi:type="object">Vendor\Module\Processor\Export</item>
        </argument>
    </arguments>
</type>

Important notes:

  • Object arguments must reference valid PHP classes or interfaces
  • The ObjectManager creates instances automatically
  • Shared objects are reused; non-shared create new instances per injection

Array, Const, and Complex Arguments

Array and const arguments handle structured configuration data.

Array arguments:

<type name="Vendor\Module\Service\ConfigurableProcessor">
    <arguments>
        <argument name="options" xsi:type="array">
            <item name="retry_count" xsi:type="number">3</item>
            <item name="retry_delay" xsi:type="number">5</item>
            <item name="mode" xsi:type="string">strict</item>
            <item name="fallback_strategy" xsi:type="string">skip</item>
        </argument>
        <argument name="allowed_types" xsi:type="array">
            <item name="0" xsi:type="string">simple</item>
            <item name="1" xsi:type="string">configurable</item>
            <item name="2" xsi:type="string">bundle</item>
        </argument>
    </arguments>
</type>

Const arguments:

<type name="Vendor\Module\Service\Logger">
    <arguments>
        <argument name="logLevel" xsi:type="const">Psr\Log\LogLevel::ERROR</argument>
        <argument name="maxFileSize" xsi:type="const">Vendor\Module\Config\Constants::MAX_LOG_SIZE</argument>
    </arguments>
</type>

Nested arrays:

<argument name="handlers" xsi:type="array">
    <item name="stream" xsi:type="array">
        <item name="type" xsi:type="string">stream</item>
        <item name="level" xsi:type="number">100</item>
        <item name="bubble" xsi:type="boolean">false</item>
    </item>
    <item name="rotating" xsi:type="array">
        <item name="type" xsi:type="string">rotating</item>
        <item name="max_files" xsi:type="number">30</item>
    </item>
</argument>

Merging arrays across scopes:

<!-- etc/di.xml (global) -->
<type name="Vendor\Module\Service\Processor">
    <arguments>
        <argument name="modes" xsi:type="array">
            <item name="0" xsi:type="string">default</item>
        </argument>
    </arguments>
</type>

<!-- etc/frontend/di.xml (frontend) -->
<type name="Vendor\Module\Service\Processor">
    <arguments>
        <argument name="modes" xsi:type="array">
            <item name="1" xsi:type="string">frontend_only</item>
        </argument>
    </arguments>
</type>

Array arguments are merged by key. Numeric keys are re-indexed.

Argument Overriding and Scope Precedence

Arguments can be overridden at different scopes, with area-specific configurations taking precedence.

Scope precedence order:

  1. webapi_rest/di.xml
  2. webapi_graphql/di.xml
  3. adminhtml/di.xml
  4. frontend/di.xml
  5. crontab/di.xml
  6. etc/di.xml (global)

Overriding example:

<!-- etc/di.xml (global) -->
<type name="Vendor\Module\Service\Logger">
    <arguments>
        <argument name="logLevel" xsi:type="string">info</argument>
        <argument name="logFile" xsi:type="string">var/log/module.log</argument>
    </arguments>
</type>

<!-- etc/adminhtml/di.xml (admin only) -->
<type name="Vendor\Module\Service\Logger">
    <arguments>
        <argument name="logLevel" xsi:type="string">debug</argument>
    </arguments>
</type>

Result in adminhtml area:

  • logLevel = debug (overridden)
  • logFile = var/log/module.log (inherited)

Module load order override:
Later modules can override arguments set by earlier modules:

<!-- Module A: etc/di.xml -->
<type name="Magento\Catalog\Model\ResourceModel\Product">
    <arguments>
        <argument name="connectionName" xsi:type="string">default</argument>
    </arguments>
</type>

<!-- Module B: etc/di.xml (loads after Module A) -->
<type name="Magento\Catalog\Model\ResourceModel\Product">
    <arguments>
        <argument name="connectionName" xsi:type="string">replica</argument>
    </arguments>
</type>

Debugging arguments:

# Check compiled DI configuration
cat var/di/etc/module.xml

# Inspect ObjectManager
$objectManager->get(Processor::class);

Quiz

1. What xsi:type is used to pass a PHP class constant as an argument?

Question 1 options

2. How are array arguments merged across global and area-specific di.xml?

Question 2 options

3. What happens if a scalar type constructor parameter has no di.xml argument and no default value?

Question 3 options

4. How do you make an object dependency optional via di.xml?

Question 4 options

Flashcards

Question

What are the available xsi:type values for di.xml arguments?

Answer

string, number, boolean, object, array, const, null

Question

What is the scope precedence for argument overriding?

Answer

webapi_rest > webapi_graphql > adminhtml > frontend > crontab > global

Question

How are array arguments merged across scopes?

Answer

By key, with area-specific values taking precedence

Question

Why can't scalar types be auto-resolved?

Answer

ObjectManager cannot infer literal values without configuration or defaults

Question

What is a common use case for xsi:type="const"?

Answer

Passing PHP class constants as configuration values

Revision Notes

Key Takeaways

  • 1. String and number arguments pass literal scalar values to constructors
  • 2. Boolean arguments control feature flags; null makes dependencies optional
  • 3. Object arguments inject specific classes, interfaces, or virtual types
  • 4. Array arguments support nested structures and merge by key across scopes
  • 5. Const arguments reference PHP class constants
  • 6. Area-specific di.xml overrides global arguments for the same key

Interview Tips

  • Explain why scalar types need explicit di.xml configuration
  • Describe how to make an object dependency optional
  • Show examples of nested array arguments
  • Discuss argument merging behavior across scopes

Cheat Sheet

di.xml Arguments Cheat Sheet

Types:

  • xsi:type="string" → PHP string
  • xsi:type="number" → PHP int/float
  • xsi:type="boolean" → PHP bool
  • xsi:type="object" → PHP class instance
  • xsi:type="array" → PHP array (mergeable)
  • xsi:type="const" → PHP constant value
  • xsi:type="null" → PHP null

Scope Precedence:
webapi_rest > webapi_graphql > adminhtml > frontend > crontab > global

Array merge rule: Merge by key, later scope wins on conflicts