How to use DRY on identical code inside several factories?

expressive

#1

I have several factories, each of which uses the same initialization code for a $quote_id.

Code here

Imagine I have several factories like the above, and each of them contains the same lines for $quote_id.

Is there a way to use DRY on this to where I only retrieve quote id once? I could place that code into the container, but where is the place to put that code into the container as far as bootstrapping Expressive goes?
Also, I do not always need the $quote_id, so I do not want to retrieve it for every request.


#2

Based on conversations in Slack, I think you may have answered this already. The idea is that you should create a factory for generating your MyRepository instances. This factory will compose either the ContainerInterface or the MySql instance. You would compose the factory in your middleware/actions, and pass the factory the related user input in order to get your repository:

class MyRepositoryFactory
{
    private $sql;

    public function __construct(MySql $sql)
    {
        $this->sql = $sql;
    }

    public function createRepository($quoteId)
    {
        return new MyRepository($quoteId, $this->sql);
    }
}

class MyRepositoryFactoryFactory
{
    public function __invoke(ContainerInterface $container)
    {
        return new MyRepositoryFactory($container->get(MySql::class));
    }
}

class MyFormAction implements MiddlewareInterface
{
    private $repositoryFactory;
    private $renderer;

    public function __construct(MyRepositoryFactory $repositoryFactory, TemplateRendererInterface $renderer)
    {
        $this->repositoryFactory = $repositoryFactory;
        $this->renderer = $renderer;
    }

    public function process(ServerRequestInterface $request, DelegateInterface $delegate)
    {
        $repository = $this->repositoryFactory->createRepository($request->getQueryParams()['quote_id'] ?? 0);

        // ...
    }
}