Skip to content

Remove container dependency #13

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jaapio
Copy link

@jaapio jaapio commented Jan 23, 2017

Client was leaking the applications container. When needed the
container can inject itself into handlers. There is no need to have this
in the client.

Beside that this pr removes the hard connection with php-di, which allows the user of the package to choose there own DIC. Without having multiple DIC's in your application.

@@ -19,12 +19,13 @@ public static function create(
LoopInterface $loop,
array $options = []
): Client {
$container = self::createContainer($loop, $options);
return new Client(
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually need this method? This factory should return the commandbus, not the client?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually returning the command bus instead of the client makes sense. Clients should using it building their client and abstract all operations into it 👍 .

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore this comment for now. It would be something for a follow up PR, like to explore the idea though.

@WyriHaximus
Copy link
Member

This makes a lot of sense. I needed the leak at some point, will look it up, test this PR with that client before I respond. But while skimming over it this looks good 👍

Copy link
Member

@WyriHaximus WyriHaximus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great step in the right direction, but this PR as of right now has some contradictions.

src/Factory.php Outdated
);
}

private static function createContainer(LoopInterface $loop, array $options): ContainerInterface
public static function createContainer(LoopInterface $loop, array $options): ContainerInterface
{
$container = new ContainerBuilder();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While you removed PHP-DI from dependencies this ContainerBuilder is still a concrete class from PHP-DI.

composer.json Outdated
@@ -15,13 +15,14 @@
"api-clients/hydrator": "dev-master",
"api-clients/service": "dev-master",
"api-clients/transport": "dev-master",
"league/event": "^2.1",
"php-di/php-di": "^5.4"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% sure if we should do this. The foundation providers a container for the application/client, and patching the leakage should hide it from the application. If we want to give applications access to adding definitions we could use the same kind of construction as we do with the command bus, some extra configuration in composer.json: https://github.com/php-api-clients/github/blob/master/composer.json#L38-L45

(No need to do that in this PR though 😄 .)

@jaapio
Copy link
Author

jaapio commented Jan 25, 2017

What I intended to do was removing PHP-DI as dependency. Since that was only needed in this factory. Most applications will use there own DIC, so removing this dependency was needed to not have multiple DICs in one application.

To accomplish this I removed the getters from the Client that where never used by any of the projects in this organisation. So I thought it was safe to remove them. But I didn't want to break your Factory. So I left the dependency as is here.

The ContainerInterface only specifies the get and has methods and no way to configure containers. So when you want to use an other DI package, you will have to write your own factory. The whole createContainer method is not usable in this case.

Maybe we should do a step back to have a look at this implementation and why it is needed. When developing a api-client library that's meant to be used in an application. So from my point of view it should only have the dependencies that are required to get the client working.
All libraries will implement an AsyncClient, that needs an implementation of ApiClients\Foundation\ClientInterface. Basically that's just a wrapper around the CommandBus. But to hide that from the implementation it feels good to have this implementation.

The CommandBus itself doesn't need the ContainerInterface but the middelware (CommandHandlerMiddleware) that's injected does.
Same thing for Transport and Hydrators.

There is a lot of magic going on in the implementations of Transport and Hydrators to fetch their dependencies. I would like to make this more explicit. I tried to do that with this first step. And when I was writing this comment I saw why I feld it this way. It looks like the ContainerInterface is everywhere, And there is a hard binding to PHP-DI or an equal DIC. There is no way to use a ServiceLocator like Zend-ServiceManager for example because to much magic is involved.

@WyriHaximus
Copy link
Member

[...]

There is a lot of magic going on in the implementations of Transport and Hydrators to fetch their dependencies. I would like to make this more explicit.

Absolutely 👍 ! Things have come a long way since I've started working on this project 6+ months ago and some of it still holds legacy from that long lost past. I'm glad to see you're picking these issues up and looking at it with a fresh pair of eyes 😄 .

Would the application be injecting it's DIC/Service Locator into a client or would the client hold it's own private internal DIC/Service Locator? We could do both where we look into this PHP-DI feature combining a passed in container for extra entries and our own for hydrator, transport, etc. We still ensure all components type hint against the container interop interface so they don't care.

Could you make issues/PR's on the different components describing your ideas or work them out in a PR and reference between them? Might be easier discussing changes that way.

P.S. As far a breaking things goes, we're still in dev-master if a break makes sense lets break it. If we're in 0.x we go to 0.y. If we're in stable releases we break and tag another major release. Especially since non of the clients have been tagged yet 😄 . The only thing to keep in mind is to coordinate breaking PR's with updating all other packages relying and influenced but that change.

@jaapio
Copy link
Author

jaapio commented Jan 9, 2018

Anything I can do to have this merged?

@WyriHaximus
Copy link
Member

Just skimmed over it and for some reason it made a lot of sense now. Not sure what I was missing last year 🤐 . Can you resolve the conflicts with master?

jaapio added 2 commits January 9, 2018 21:51

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Client was leaking the applications container. When needed the
container can inject itself into handlers. There is no need to have this
in the client.
@jaapio jaapio force-pushed the remove-container-dependency branch from 6765bad to 3012b77 Compare January 9, 2018 21:02
@jaapio
Copy link
Author

jaapio commented Jan 9, 2018

I rebased it, but it was way to long ago to remember what I was doing that the moment of this pr :-( so I hope that this fits your needs

@WyriHaximus
Copy link
Member

Yeah there are a few different things happening. But the main thing for me, is to remove the container from injecting it self into the Client. Will request a few changes to make that the main goal for the PR if you agree?

@jaapio
Copy link
Author

jaapio commented Jan 9, 2018

👍 will do the rework after your review.

@@ -14,7 +14,6 @@
"api-clients/hydrator": "^1.0.1",
"api-clients/middleware": "^4.0 || ^3.0 || ^2.0 || ^1.1",
"api-clients/transport": "^3.0 || ^2.0 || ^1.0",
"php-di/php-di": "^5.4.3",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you revert this, PHP-DI was specifically picked for the autowiring of dependencies for services and handlers used throughout the entire @php-api-clients project. External definitions are supported through https://github.com/php-api-clients/foundation/blob/master/src/Factory.php#L53 but I would like to support wrappoing an external PSR-11 container in the future.

/**
* @return mixed
*/
public function getFromContainer(string $id);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only used in two clients and from I've gathered it can easily updated after this fix 👍

@@ -19,12 +19,13 @@ public static function create(
LoopInterface $loop,
array $options = []
): Client {
$container = self::createContainer($loop, $options);
return new Client(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore this comment for now. It would be something for a follow up PR, like to explore the idea though.

{
$loop = LoopFactory::create();

$stdClass = new \stdClass();
$stdClass->foo = 'bar';

$client = Factory::create(
$container = Factory::createContainer(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this blow up since Factory::createContainer is private?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants