If you’re being a good Magento 2 programmer, you’re not directly accessing an object manager instance. You’re using dependency injection to inject your objects in a constructor so future programmers will have a clear place to see a class’s dependencies, and change them if need be.
But we know good programmers aren’t always good developers.
Even the Magento core team sometimes dips into using an object manager instance directly, and while I wouldn’t recommend it for shipping production code, using an object manager can be much faster for prototyping new ideas or when you’re working with an unfamiliar part of the object hierarchy.
This is all covered in my Object Manager series, but its worth mentioning here again.
When you use the object manager’s get
method, you’re creating a “singleton version” (sorry CS folks!) of an object, or a shared instance.
$object = $object_manager->get('FooBazModelBar');
Every time you use the above code, Magento will return the same FooBazModelBar
object. If one part of your code sets data on this object, it will be reflected elsewhere in the system.
If you use the create
method
$object = $object_manager->create('FooBazModelBar');
Magento will instantiate a new object, or an unshared instance i.e., roughly equivalent to
$object = new FooBazModelBar;
Understanding how DI Injects Objects
When you inject an object via automatic constructor dependency injection
public function __construct(FooBazModelBar $foo)
{
//...
}
Magento 2, by default, uses the get
method. This is “the right” thing to do from a systems point of view – less objects instantiated means better system performance. However, it can be confusing for folks thinking on the application level. These “client programmers” might not expect these objects to be shared with other parts of the system.
Automatic constructor dependency injection also supports injecting objects via create
instead of get
. If an object’s type is defined in a loaded di.xml
file, and that object’s type includes a shared="false"
<type name="FooBazModelBar" shared="false"/>
Magento will use create
when injecting the object. Generally speaking, this feels like it should be avoided. There’s zero feedback when a programmer is looking at class as to which objects may or may not be shared instances. If you need an unshared instance, its better to use the automatic factory generation features of Magento 2 to inject a factory, and then use the factory’s create method
public function __construct(FooBazModelBarFactory $factory)
{
$this->barFactory = $factory;
$this->barInstance = $this->barFactory->create();
}
public function someFunction()
{
$object = $this->barFactory->create();
}