moduleConfig: A virtual type that extends the type Magento\Core\Model\Config.

Magento\Core\Model\App: All instances of this type receive an instance of moduleConfig as a dependency.

Virtual types

A virtual type
allows you to change the arguments of a specific injectable dependency and change the behavior of a particular class.
This allows you to use a customized class without affecting other classes that have a dependency on the original.

The example creates a virtual type for Magento\Core\Model\Config and specifies system as the constructor argument for type.

Constructor arguments

You can configure the class constructor arguments in your di.xml in the argument node.
The object manager injects these arguments into the class during creation.
The name of the argument configured in the XML
file must correspond to the name of the parameter in the constructor in the configured class.

The following example creates instances of Magento\Core\Model\Session with the class constructor argument $sessionName set to a value of adminhtml:

Magento builds an array with elements corresponding to the items and passes it as the argument.
The array can contain an infinite number of items, and each array item can be of any object type including an array itself.

When Magento merges the configuration files for a given scope, array arguments with the same name get merged into a new array.

When Magento loads a new configuration at a later time, either by a more specific scope or through code, then any array definitions in the new configuration will replace the loaded config instead of merging.

During merging, arguments replace other arguments with the same name if their type is different.
If the argument type is the same, then the newer argument replaces the old one.

Abstraction-implementation mappings

The object managers uses the abstraction-implementation mappings when the constructor signature of a class requests an object by its interface.
The object manager uses these mappings to determine what the default implementation is for that class for a particular scope.

This mapping is in app/etc/di.xml, so the object manager injects the Magento\Core\Model\Url implementation class wherever there is a request for the Magento\Core\Model\UrlInterface in the global scope.

This mapping is in app/code/core/Magento/Backend/etc/adminhtml/di.xml, so the object manager injects the Magento\Backend\Model\Url implementation class wherever there is a request for the Magento\Core\Model\UrlInterface in the admin
area.

Parameter configuration inheritance

Parameters configured for a class type pass on its configuration to its descendant classes.
Any descendant can override the parameters configured for its supertype; that is, the parent class or interface:

The first entry configures all instances of Magento\Framework\View\Element\Context as well as its children to pass in Magento\Core\Model\Url as $urlBuilder in their constructors.

The second entry overrides this and configures all instances of Magento\Backend\Block\Context to use Magento\Backend\Model\Url as the $urlBuilder instead.

Object lifestyle configuration

The lifestyle of an object determines the number of instances that can exist of that object.

You can configure dependencies in Magento to have the following lifestyles:

singleton(default) - One instance of this class exists. The object manager creates it at the first request.
Requesting the class again returns the same instance.
Disposing or ending the container registered to it releases the instance.

transient - The object manager creates a new instance of the class for every request.

The shared property determines the lifestyle of both argument and type configurations.

In this example Magento\Filesystem is not shared, so all clients will retrieve separate instances of Magento\Filesystem.
Also, every instance of Magento\Filesystem will get separate instance of $adapter, because it too is non-shared.