Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DI] add ReverseContainer: a locator that turns services back to their ids #30334

Merged

Conversation

@nicolas-grekas
Copy link
Member

commented Feb 21, 2019

Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets -
License MIT
Doc PR -

This PR introduces a ReverseContainer, which is a class you can type hint for to get it as a service.

When you have a ReverseContainer at hand, you can then use it to know the service id of an object (if the object is not found, null is returned):
$id = $reverseContainer->getId($someObject);

You can also call $reverseContainer->getService($id); and get the service in return.

To be reversible, a service must either be public or be tagged with container.reversible.

I'm using this feature to serialize service references in a message, then send them through a Messenger bus, allowing the handler on the other side to use that referenced service to process the message. More specifically, my use case is sending messages for early cache expiration events through a bus and have a worker compute the soon-to-expire value in the background. The reversible services are the computation callbacks and the cache pools I need to compute the value for.

@linaori
Copy link
Contributor

left a comment

I'm always amazed with your solutions 👍 !

@nicolas-grekas nicolas-grekas force-pushed the nicolas-grekas:di-referenceable-container branch from 780a6df to fe4d7de Feb 22, 2019

@nicolas-grekas nicolas-grekas force-pushed the nicolas-grekas:di-referenceable-container branch 3 times, most recently from f8a22fc to b6eefca Feb 22, 2019

@nicolas-grekas

This comment has been minimized.

Copy link
Member Author

commented Mar 8, 2019

Show resolved Hide resolved src/Symfony/Component/DependencyInjection/ReverseContainer.php Outdated
*
* @throws ServiceNotFoundException When the service is not reversible
*/
public function getService(string $id)

This comment has been minimized.

Copy link
@Tobion

Tobion Mar 9, 2019

Member

Why not let people use a normal service locator for this?

This comment has been minimized.

Copy link
@nicolas-grekas

nicolas-grekas Mar 9, 2019

Author Member

Because it's not a normal service locator: you can get here only the ids you can fetch with the other method before. It wouldn't make sense to provide a standard locator interface here Having a different interface highlights this is not the same kind as a regular locator.

This comment has been minimized.

Copy link
@Tobion

Tobion Mar 9, 2019

Member

isn't it the same as having a service locator for services tagged with container.reversible that you can easily do manually?

This comment has been minimized.

Copy link
@nicolas-grekas

nicolas-grekas Mar 9, 2019

Author Member

those, + public services

This comment has been minimized.

Copy link
@Tobion

Tobion Mar 9, 2019

Member

So why does it need the method then?

This comment has been minimized.

Copy link
@nicolas-grekas

nicolas-grekas Mar 9, 2019

Author Member

Because an instance of this class is a single consistent scope of services you can reverse.
Providing only object->id mapping here, and relying on another object to do the reverse would mean the two objects would be bound by some external convention that cannot be enforced by any contracts. Having both methods in this class is what provides the needed guarantee, from the abstraction pov.

@nicolas-grekas nicolas-grekas force-pushed the nicolas-grekas:di-referenceable-container branch from b6eefca to a2515ee Mar 9, 2019

@nicolas-grekas nicolas-grekas force-pushed the nicolas-grekas:di-referenceable-container branch 2 times, most recently from 9046dbb to 6533251 Mar 9, 2019

@nicolas-grekas nicolas-grekas force-pushed the nicolas-grekas:di-referenceable-container branch from 6533251 to 3ffe1fe Mar 9, 2019

@nicolas-grekas nicolas-grekas force-pushed the nicolas-grekas:di-referenceable-container branch from 3ffe1fe to c8dfc57 Mar 10, 2019

@nicolas-grekas nicolas-grekas requested review from chalasr and Tobion Mar 12, 2019

@nicolas-grekas nicolas-grekas force-pushed the nicolas-grekas:di-referenceable-container branch from c8dfc57 to ac1e429 Mar 14, 2019

@nicolas-grekas nicolas-grekas merged commit ac1e429 into symfony:master Mar 15, 2019

3 checks passed

continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
fabbot.io Your code looks good.
Details

nicolas-grekas added a commit that referenced this pull request Mar 15, 2019

feature #30334 [DI] add ReverseContainer: a locator that turns servic…
…es back to their ids (nicolas-grekas)

This PR was merged into the 4.3-dev branch.

Discussion
----------

[DI] add ReverseContainer: a locator that turns services back to their ids

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

This PR introduces a `ReverseContainer`, which is a class you can type hint for to get it as a service.

When you have a `ReverseContainer` at hand, you can then use it to know the service id of an object (if the object is not found, `null` is returned):
`$id = $reverseContainer->getId($someObject);`

You can also call `$reverseContainer->getService($id);` and get the service in return.

To be reversible, a service must either be public or be tagged with `container.reversible`.

I'm using this feature to serialize service references in a message, then send them through a Messenger bus, allowing the handler on the other side to use that referenced service to process the message. More specifically, my use case is sending messages for early cache expiration events through a bus and have a worker compute the soon-to-expire value in the background. The reversible services are the computation callbacks and the cache pools I need to compute the value for.

Commits
-------

ac1e429 [DI] add ReverseContainer: a locator that turns services back to their ids

@nicolas-grekas nicolas-grekas deleted the nicolas-grekas:di-referenceable-container branch Mar 15, 2019

@nicolas-grekas nicolas-grekas modified the milestones: next, 4.3 Apr 30, 2019

@fabpot fabpot referenced this pull request May 9, 2019

Merged

Release v4.3.0-BETA1 #31435

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.