Skip to content

Conversation

@SamMousa
Copy link
Contributor

No description provided.

@innocenzi innocenzi changed the title fix(container): add docs for https://github.com/tempestphp/tempest-framework/pull/1090 lazy injection feat: document lazy injections Mar 28, 2025
@innocenzi
Copy link
Member

Could you maybe find some kind of realistic example where this might be used?

@SamMousa
Copy link
Contributor Author

SamMousa commented Mar 28, 2025

Harder than expected... I've spent a lot of my time removing the need for this in most of my code (ie do as little as possible in the constructor).

One example might be the CacheClearCommand:

final readonly class CacheClearCommand
{
    public function __construct(
            private CacheConfig $cacheConfig,
            private Container $container,
        ) {}
}

It depends on the container and on a CacheConfig object that has a list of class names for caches that it can retrieve from the container.

It'd be cleaner code if you could just pass in the cache instances:

public function __construct(private \Tempest\Cache\Cache ...$caches) {

}

However this would be bad if you're instantiating all those caches just to clear one. Here lazy would be perfect.

Sidenote: I don't actually know how DI currently works with variadic arguments in Tempest; I've not tested if #[Lazy] currently works for it.

Essentially it's useful for any case where construction of an object and its dependencies is something you want to avoid.
Of course, if it's your own code ideally you refactor it so construction is cheaper, but most of the time you don't control all code used by the project.

@innocenzi
Copy link
Member

Yeah, I understand what it does, but I can't think of any situation where I'd use that, which is why I asked 😬

@SamMousa
Copy link
Contributor Author

Yeah it's a fair question for sure. You'd only use it for code that is suboptimal to begin with I guess.

I'd say you'd always want to use it when using something like GenericHttpClient as a dependency that you might not need, it has a big dependency tree:

- GenericHttpClient
-- Psr18Driver
--- ClientInterface
--- UriFactoryInterface
--- RequestFactoryInterface
--- StreamFactoryInterface

But then again, if you conclude that the cost of initializing the full tree are negligible you don't want to optimize for it.

@SamMousa
Copy link
Contributor Author

I think Amazon's S3 client is a good example. (It's one of the very few dependencies that I lazy load)!

@brendt brendt merged commit 7e49c75 into tempestphp:main Apr 2, 2025
1 of 3 checks passed
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.

3 participants