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.

The legacy

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 Magento\Framework\Model\EntityManager.

Discovering the EntityManager

The 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 Magento\Framework\EntityManager\Operation\Update.

The general 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.

In practice

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 EntityManager:

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 EntityManager.

Next, any CRUD method (save, delete, 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).