Working with the new Magento 2.1 Entity Manager
With Magento 2.1, a new class structure has been introduced - dubbed the Entity Manager - which allows for a better structure to work with entities through composition, instead of relying upon parent classes to do the work. Let's see what's inside this new class.
DISCLAIMER: Currently the Entity Manager is still experimental. Also see this discussion on StackExchange.
Previously, with Magento 2.0, you could build yourself a MVC module and have your models extend from classic Abstract models like
Magento\Framework\Model\AbstractModel. This allowed for a lot of functionality, which is great - but it was actually so much functionality that the parent classes got overloaded which by itself was a code smell. Instead of adding the needed functionality with inheritance, Magento 2.1 tries to solve this through composition (composition over inheritance) by introducing the class
Discovering the EntityManager
EntityManager class relies on the
OperationPool class (
Magento\Framework\EntityManager\OperationPool) to get certain operations that can be run on the entity itself. For instance, writing changes for an existing entity to the database (i.e. an update) is done using an operation subclass
app/etc/di.xml gives clues on how this works: Whenever
OperationPool is instanted, a
type definition tells the Object Manager to instantiate the
OperationPool with a list of
operations. Because this is defined in XML, other modules can add new operations to this list. The
EntityManager itself injects itself with a new instance of
OperationPool through a simple constructor injection.
There's kind of a lot of layers when interacting with data. First of all, a repository is used so that other logic (controllers, helpers, blocks or other models) can safely interact with a database-driven model, without knowing anything (well, not much) of its actual database structure. The repository acts as frontend to either the collection or the singular model. This singular model has both an abstract model and a resource model. Both the abstract (regular) model and the resource model used to have a lot of logic. This has changed with the coming of the
A good example of seeing the
EntityManager in action is the
Magento\Catalog\Model\ResourceModel\Product class: It injects itself with an instance of the
EntityManager - well, not through constructor argument but via a hack with the Object Manager: I would suggest you simply use constructor injection to get your instance of
Next, any CRUD method (
load) is simply deferred to the
EntityManager instead. If you look at the
Product example, you might spot that it is extending from the old
Magento\Catalog\Model\AbstractModel class. It might be that this will also be the case in the future. But the main idea is that logic is transferred from that original parent (inheritance) into separate manager classes (composition).