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

Lazy load interface definitions for generated factories #129

Closed
JanTvrdik opened this issue Oct 23, 2016 · 9 comments
Closed

Lazy load interface definitions for generated factories #129

JanTvrdik opened this issue Oct 23, 2016 · 9 comments

Comments

@JanTvrdik
Copy link
Contributor

@JanTvrdik JanTvrdik commented Oct 23, 2016

Currently calling $configurator->loadContainer() triggers autoloading for all interfaces implemented by generated factories (which because of parameter and return types cause loading their dependencies…)

The solution is to either move implementation of generated factories to different file or to move it to runtime (possible utilizing anonymous classes in PHP 7)

/**
 * @return App\Components\MyComponent
 */
public function createService__248()
{
    return new class($this) implements App\Components\IMyComponentFactory
    {
        private $container;


        public function __construct(Container_7bc42fd40e $container)
        {
            $this->container = $container;
        }


        public function create(): App\Components\MyComponent
        {
            return new App\Components\MyComponent();
        }
    };
}
@lookyman

This comment has been minimized.

Copy link
Contributor

@lookyman lookyman commented Oct 24, 2016

The anonymous class solution would actually solve a problem I encountered just last week, where I tried to auto generate the interface itself. It works, but if you put it somewhere where the autoloading you already have doesn't see it, you are screwed. You have to either extend the PSR-4 autoload in composer.json, or register new path in RobotLoader in bootstrap. Neither of which you can do in runtime from an extension.

But, PHP 7 :/

Relevant https://github.com/lookyman/di/commit/6674d280d9f2911b63309903df20556315a2b2e2

@dg

This comment has been minimized.

Copy link
Member

@dg dg commented Oct 24, 2016

👍

@dg dg closed this in 9b41dbb Oct 26, 2016
@TomasVotruba

This comment has been minimized.

Copy link
Contributor

@TomasVotruba TomasVotruba commented Oct 27, 2016

@lookyman How exactly in your case? And what was your issue? I didn't get that from referenced method.

@lookyman

This comment has been minimized.

Copy link
Contributor

@lookyman lookyman commented Oct 27, 2016

@TomasVotruba

I had an extension, gave it some path, it scanned it for all classes of some type, generated a factory interface for each of them (and wrote it to some file in another path), and registered that interface as a service in container. But if that path with generated interfaces was not under autoload, the container couldn't be instantiated (though it could be built).

Kdyby/Doctrine, for example, runs into similar issue for generated entity proxies. But the proxies are loaded when the application is already running, so you have time to register an autoloader in Container::initialize(). In my case, you don't.

I have since abandoned that idea, but the commit I referenced could be used to solve this issue. Although I would much rather use the already existing afterCompile() for this and pass it a reference to all generated classes, but that would be a big BC break.

@TomasVotruba

This comment has been minimized.

Copy link
Contributor

@TomasVotruba TomasVotruba commented Oct 28, 2016

@lookyman Pretty neat usage :) thanks for explaining.

Do you have this extension somewhere on Github? Would love to see that.

@lookyman

This comment has been minimized.

Copy link
Contributor

@lookyman lookyman commented Oct 29, 2016

@TomasVotruba https://github.com/lookyman/nette-auto-factory I need to stress that it has massive limitations (constructor arguments) and is basically just an exercise in using PhpGenerator.

@TomasVotruba

This comment has been minimized.

Copy link
Contributor

@TomasVotruba TomasVotruba commented Nov 9, 2016

@lookyman I was wondering... how far from your package is to create same service lazy loader (using proxy) that has Symfony?
https://symfony.com/doc/current/service_container/lazy_services.html

That would be awesome extension :)

@dg

This comment has been minimized.

Copy link
Member

@dg dg commented Nov 13, 2016

The problem with autogenerated intefaces is that is then you use in the code interfaces that actually don't exist. It will break code completing in IDE or API documentation generators.

Proxies don't have these problems, but they have another.

@lookyman

This comment has been minimized.

Copy link
Contributor

@lookyman lookyman commented Nov 14, 2016

@dg I know, as I've said, that whole extension was just an excercise. Not really that useful, except perhaps in very specific circumstances.

Anyway, I LOVE the anonymous class thingy you've made here. Thanks.

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