zen icon indicating copy to clipboard operation
zen copied to clipboard

Inject with non-scalar value?

Open ellisgl opened this issue 11 months ago • 2 comments

I'm playing around with tomrf/htmx-message and to get a Request object, you need to do the following:

<?php
use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7Server\ServerRequestCreator;
use Tomrf\HtmxMessage\HtmxServerRequest;

$psr17Factory = new Psr17Factory();
$creator = new ServerRequestCreator(
    $psr17Factory, // ServerRequestFactory
    $psr17Factory, // UriFactory
    $psr17Factory, // UploadedFileFactory
    $psr17Factory  // StreamFactory
);

// Wrap the request with HTMX proxy.
$request = new HtmxServerRequest($creator->fromGlobals());

How could I override the parameter with a function call? (Or any other to build this dependency)

ellisgl avatar Jul 15 '23 16:07 ellisgl

Just in case anyone wants to see the ContainerConfig:

<?php
declare(strict_types=1);

namespace App\Container;

use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7\Response;
use Nyholm\Psr7Server\ServerRequestCreator;
use Nyholm\Psr7Server\ServerRequestCreatorInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestFactoryInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\UploadedFileFactoryInterface;
use Psr\Http\Message\UriFactoryInterface;
use Tomrf\HtmxMessage\HtmxResponse;
use Tomrf\HtmxMessage\HtmxServerRequest;
use WoohooLabs\Zen\Config\AbstractContainerConfig;
use WoohooLabs\Zen\Config\EntryPoint\EntryPointInterface;
use WoohooLabs\Zen\Config\EntryPoint\Psr4NamespaceEntryPoint;
use WoohooLabs\Zen\Config\Hint\DefinitionHint;
use WoohooLabs\Zen\Config\Hint\DefinitionHintInterface;
use WoohooLabs\Zen\Config\Hint\WildcardHintInterface;
use WoohooLabs\Zen\Exception\ContainerException;

class ContainerConfig extends AbstractContainerConfig
{
    /**
     * {@link https://github.com/woohoolabs/zen#entry-points}
     * Entry Points are such classes that are to be directly retrieved from the DI Container.
     * Controllers and Middleware usually fall in this category.
     * This means that you can only fetch Entry Points from the Container
     * with the $container->get() method and nothing else.
     *
     * @return array | string[] | EntryPointInterface[]
     */
    protected function getEntryPoints(): array
    {
        return [
            new Psr4NamespaceEntryPoint('App\\Controller')
        ];
    }

    /**
     * {@link https://github.com/woohoolabs/zen#hints}
     * Hints tell the compiler how to properly resolve a dependency.
     * This can be necessary when you depend on an interface or an abstract class
     * because they are obviously not instantiatable.
     * With hints, you are able to bind implementations to your interfaces or concretions to your abstract classes.
     *
     * @return array | string[] | DefinitionHintInterface[]
     * @throws ContainerException
     */
    protected function getDefinitionHints(): array
    {
        return [
            // ContainerInterface::class => Container::class,
            ServerRequestFactoryInterface::class => Psr17Factory::class,
            UriFactoryInterface::class => Psr17Factory::class,
            UploadedFileFactoryInterface::class => Psr17Factory::class,
            StreamFactoryInterface::class => Psr17Factory::class,
            ServerRequestCreatorInterface::class => ServerRequestCreator::class,
            ServerRequestInterface::class => '',
            // Bind the Request class to the RequestInterface (Prototype scope)
            RequestInterface::class => DefinitionHint::prototype(HtmxServerRequest::class),
            // Bind the Response class to the ResponseInterface (Singleton scope)
            ResponseInterface::class => DefinitionHint::singleton(HtmxResponse::class)
                                                      ->setParameter('message', Response::class),
        ];
    }

    /**
     * {@link https://github.com/woohoolabs/zen#hints}
     * Wildcard Hints can be used when you want to bind your classes in masses.
     * Basically, they recursively search for all your classes in a directory specified by the first parameter,
     * and bind those classes together which can be matched by the provided patterns.
     *
     * @return array | WildcardHintInterface[]
     */
    protected function getWildcardHints(): array
    {
        return [
            // new Psr4WildcardHint(
            //    'WoohooLabs\Zen\Examples\Domain\*RepositoryInterface',
            //    'WoohooLabs\Zen\Examples\Infrastructure\Mysql*Repository'
            // ),
        ];
    }
}

ellisgl avatar Jul 18 '23 03:07 ellisgl

Hi @ellisgl ,

Passing non-scalar arguments to the container is not supported due to technical limitations when building the container: this process basically means that container definitions are serialized, and non-scalar values cannot be serialized without extra magic..

For the next major release of Zen, we could use https://github.com/opis/closure or something similar for the use-case, but I couldn't find the time to work on this feature yet.

kocsismate avatar Jul 28 '23 09:07 kocsismate