Currently we are using procedural wrappers for our entity controllers: entity_form_controller(); entity_get_controller() etc. It might be good to register those with the DIC directly. Discuss!

CommentFileSizeAuthor
#2 1821662-2.patch4.87 KBfubhy
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

fago’s picture

What about register each controller direclty in the controller? E.g.

entity.storage.ENTITY_TYPE
entity.form.ENTITY_TYPE
entity.render.ENTITY_TYPE
entity.access.ENTITY_TYPE
entity.query.ENTITY_TYPE

We could still keep our procedural wrappes and access the DIC there. That should make conversion easy.

Related issue: #1807042: Reorganizie entity storage/list/form/render controller annotation keys

fubhy’s picture

Status: Active » Needs review
FileSize
4.87 KB

I gave this a quick test-spin and it seems to work nicely. I ran the entity tests locally and they were green. Let's see what the testbot says.

fubhy’s picture

@fago: I used this pattern instead: 'entity.ENTITY_TYPE.CONTROLLER_TYPE'.

And yes.. I would keep the wrappers as well for convenience.

Status: Needs review » Needs work

The last submitted patch, 1821662-2.patch, failed testing.

sun’s picture

fubhy’s picture

Status: Needs work » Active
Issue tags: +WSCCI

Me too... DIC inception. I think the installation currently fails because of #1708692: Bundle services aren't available in the request that enables the module. Not 100% sure though. Will dig into that now. Also tagging with WSCCI.

Crell’s picture

This isn't really WSCCI, but good framework practice. So, tag Crell? :-P

In any case, +1. I like the naming pattern from #3, as well.

We can keep the wrappers for now, but should remove them during code slush. They're all new in D8, which means we don't need them for BC. I'd rather minimize the number of procedural wrappers we have and encourage people to realize they're using the DIC, or better yet make their code injected in the first place.

Crell’s picture

Also, we will want to do things like convert the controllers in the DIC to be fully injected, so they don't have db_* calls in them, and such. Let's get the patch green first before we do that, though. (That's maybe a follow up, albeit one we need to make sure to not forget.)

Berdir’s picture

What sun said.

Don't know much about plugins yet, but I'm not sure how this plays together. The DIC is compiled now, but would be built based on plugins? Which means that if a plugin definition is changed/altered, we need to rebuild the container? Not sure if that makes sense.

And if the controllers/handlers are not part of the plugin definition, who would be responsible for registering them?

Also, the way this is currently implemented doesn't allow to remove __construct() from the controllers, because we require that they all have the same constructor and makes passing in services like the database impossible because we don't know which services a controller might need.

fubhy’s picture

Assigned: Unassigned » fubhy
Issue tags: -WSCCI

Sorry for abusing the WSCCI tag, just wanted to have it on your radar, Crell :). Will try to get the patch green today.

fubhy’s picture

@Berdir: We have all information about our entities (including alters) when registering those services with the DIC, I am not sure why you think that we would have to rebuild the container. I might be missing something, though.

And if the controllers/handlers are not part of the plugin definition, who would be responsible for registering them?

Every controller should be part of the plugin definition. Maybe we could also find a way to add stuff to the defaults of the EntityManager. That way contrib modules could inject default controllers, etc.

Also, the way this is currently implemented doesn't allow to remove __construct() from the controllers, because we require that they all have the same constructor and makes passing in services like the database impossible because we don't know which services a controller might need.

So, constructors are not required in any case. However, you are right with the fact that custom controllers that differ from our service registration would not work out of the box. We had a similar problem with the registering the Cache Backends over at #1764474: Make Cache interface and backends use the DIC, remember? Except: In this case it is much simpler because we don't have to figure out a way to override those services outside of our bundles. The solution would be: If there is a custom implementation, override it in the bundle of the module that registers that controller.

Berdir’s picture

This and the plugin patch combined will result in the following definition chain:

plugin definition (+possible alters) <- cache (requires database by default) <- built DIC <- compiled DIC.

That means that we need to fetch a service to create the service definition, a service that needs the database, so we need to initalize that that early. Which will no longer be possible with the current implementation of #1811730: Refactor Database to rely on the DIC solely because the database then requires a parameter that is only set later on.

Second, once the DIC is compiled, it's going to be really complicated to change the plugin definition. To be able to access a new entity type, you need to clear both the plugin definition cache and rebuild the DIC at the same time, in the correct order.

The cache backend issue is not solved, and will not work that way after the bootstrap kernel is gone. See the discussion in #1810912: [meta] Decide on pluggability and the current implementation of the keyvalue backends in #1809206: KeyValueFactory hard-codes DatabaseStorage.

Something constructive to end this post, something that *might* work better would be the following DIC definition:

$container->register('entity.node.storage')
  ->setFactoryService('entity_manager')
  ->setFactoryMethod('getController')
  ->addArgument('node')
  ->addArgument('storage');

That solves the problem partially because we would no longer have hardcoded controller class names in the compiled DIC but a call to another service. I'm using something like that in the database DIC issue. But probably not everything, e.g. being able to override that for different constructor arguments.

yched’s picture

shameless plug for the people subscribed here : #1832418: Possibility of stale cache in EntityManager::$controllers

tim.plunkett’s picture

yched’s picture

I'd prefer to approach this more like #1831264: Use the Entity manager to create new controller instances.

+1.
Keeping the controllers close to where we collect the metadata they created from makes it easier to do the household (like cleanup when the base metadata is refreshed)

fubhy’s picture

Status: Active » Closed (duplicate)