bin/magento dev:di:info "Vendor\Class" prints the preference Magento resolves, the constructor arguments with any di.xml values, and every before, around and after plugin for one class or interface. It reads the global area by default, or the area you pass, like frontend or adminhtml.
That covers the two questions every DI bug comes down to: which class Magento actually builds, and what wraps it. You can stop guessing and ask.
What is the Dependency Injection Layer?
Before we dive into the dev:di:info command, it's important to understand what the dependency injection layer is and why it's important. In simple terms, the DI layer is responsible for managing the relationships between different classes in Magento. When one class needs to use another class, it can request it through the DI layer, rather than creating a new instance of the class itself.
This approach has a number of benefits, including:
- Better code organization and maintainability
- Easier testing, as dependencies can be easily mocked or replaced
- Better performance, since shared instances are reused instead of creating new objects every time (unless a type is configured with
shared="false")
The catch is that the class you type-hint is often not the class you get. A preference can swap in another class, di.xml can inject different arguments, and plugins can wrap any public method. The Object Manager assembles all of that at runtime, which is exactly why you inject dependencies through the constructor instead of building them yourself.
How to use dev:di:info
The dev:di:info argument is passed to the built-in CLI tool bin/magento. It provides information about the DI configuration for a specific class or interface. By simply passing a class or interface as an argument to the bin/magento dev:di:info command, you can see the preferences used, constructor parameters, default values, and any plugins that hook into the class or interface. This is one of many useful tools available when you execute CLI commands in Magento.
To use dev:di:info, open up your terminal and run:
bin/magento dev:di:info "class or interface name"Be sure to include double quotes around the class or interface name, because the shell eats unquoted backslashes. For example, if you wanted to see the DI configuration for the Magento\Catalog\Ui\DataProvider\Product\Listing\DataProvider class, you would run:
bin/magento dev:di:info "Magento\Catalog\Ui\DataProvider\Product\Listing\DataProvider"The output will show you all the constructor parameters and their configured values, any plugins that hook into the class, and any preferences used for the class or interface.
Passing an area
The command takes an optional second argument: the area code.
bin/magento dev:di:info "Magento\Catalog\Ui\DataProvider\Product\Listing\DataProvider" adminhtmlWithout it, you only see the global DI config from each module's etc/di.xml. Anything declared in etc/frontend/di.xml or etc/adminhtml/di.xml only shows up when you pass frontend or adminhtml (other valid areas include webapi_rest, webapi_soap, graphql and crontab). An invalid area code throws an error instead of silently falling back.
Understanding the Output
The output is long. Three tables matter:
- Constructor Parameters: Each argument of the class's constructor, the type it requests, and any value configured for it in
di.xml. If classAasks for classBin its constructor,Bshows up here as the requested type. - Plugins: These are classes that intercept method calls to a given class, allowing you to modify or augment the behavior of the base class.
- Preferences: These specify which concrete class should be used to fulfill a particular interface or abstract class. For example, if you have an interface
FooInterfaceand a concrete classBar, you might define a preference to useBarwheneverFooInterfaceis requested.
Let's look at a few examples of using dev:di:info to better understand how it works by taking a look at the output of running the above command:
Constructor Parameters
Suppose we wanted to confirm the constructor parameters for the Magento\Catalog\Ui\DataProvider\Product\Listing\DataProvider class.
After running the command, the output would show us the available constructor parameters including the Name, Requested Type, and Configured Value. Note how it let us know the values of meta and data were empty arrays:
Constructor Parameters:
+-----------------------+-------------------------------------------------------------------+------------------+
| Name | Requested Type | Configured Value |
+-----------------------+-------------------------------------------------------------------+------------------+
| name | | |
| reporting | Magento\Framework\View\Element\UiComponent\DataProvider\Reporting | |
| searchCriteriaBuilder | Magento\Framework\Api\Search\SearchCriteriaBuilder | |
| request | Magento\Framework\App\RequestInterface | |
| filterBuilder | Magento\Framework\Api\FilterBuilder | |
| storeManager | Magento\Store\Model\StoreManager | |
| meta | | <empty array> |
| data | | <empty array> |
+-----------------------+-------------------------------------------------------------------+------------------+Plugins
Let's say we want to see which plugins are hooking into this class.
Running the same command, we can check the output for any before, after or around plugins for the class. It will also show
any plugins on the preference for this class:
Plugins:
+----------------------------------------------------------+---------+-------+
| Plugin | Method | Type |
+----------------------------------------------------------+---------+-------+
| Magento\Tax\Plugin\Ui\DataProvider\TaxSettings | getData | after |
| Magento\Weee\Plugin\Ui\DataProvider\WeeeSettings | getData | after |
| Magento\Wishlist\Plugin\Ui\DataProvider\WishlistSettings | getData | after |
+----------------------------------------------------------+---------+-------+
Plugins for the Preference:
+----------------------------------------------------------+---------+-------+
| Plugin | Method | Type |
+----------------------------------------------------------+---------+-------+
| Magento\Tax\Plugin\Ui\DataProvider\TaxSettings | getData | after |
| Magento\Weee\Plugin\Ui\DataProvider\WeeeSettings | getData | after |
| Magento\Wishlist\Plugin\Ui\DataProvider\WishlistSettings | getData | after |
+----------------------------------------------------------+---------+-------+It looks like a plugin exists for the Wishlist module named WishlistSettings:
| Magento\Wishlist\Plugin\Ui\DataProvider\WishlistSettings | getData | after |If you inspect the Magento\Wishlist\Plugin\Ui\DataProvider\WishlistSettings class, you'll notice that it contains an afterGetData()
method, which confirms the tool is working properly.
This table tells you which plugins exist, but not the order they run in or how around plugins nest the others. For that, see Magento plugin execution order.
Interface Preferences
Lastly, let's inspect the first line of running the same command, but this time passing in the WishlistProviderInterface from the Magento_Wishlist module:
bin/magento dev:di:info "Magento\Wishlist\Controller\WishlistProviderInterface"And here's the first part of the output from running this command:
DI configuration for the class Magento\Wishlist\Controller\WishlistProviderInterface in the GLOBAL area
Preference: Magento\Wishlist\Controller\WishlistProvider
...This is the GLOBAL-area configuration, and it tells us there is an active preference implementing this interface: the WishlistProvider class. When you ask for WishlistProviderInterface in a constructor, that's the class you get. Pass frontend or adminhtml as the second argument to see whether an area overrides it.
Why is my plugin or preference not showing?
If dev:di:info doesn't list something you just declared, check these:
- The area. A plugin or preference in
etc/frontend/di.xmlwon't appear in the default GLOBAL output. Run the command again withfrontend(oradminhtml). - The cache. DI config is cached. Run
bin/magento cache:clean configand try again. - Compiled code. In production mode, Magento reads the compiled config from
generated/. Re-runbin/magento setup:di:compileafter changingdi.xml. - The module. Make sure the module declaring it is enabled with
bin/magento module:status Vendor_Module.
Conclusion
Run dev:di:info before you start reading di.xml files by hand. It answers in one command what would otherwise take a dozen greps across vendor/, and passing the area answers the rest.
If this was useful, the plugin side of the story continues in plugins vs. observers in Magento 2.



