# What's your opinion on a factory provider?

**URL:** <https://discourse.laminas.dev/t/whats-your-opinion-on-a-factory-provider/104>\
**Category:** Mezzio\
**Created:** [May 8, 2017, 1:07pm UTC](https://discourse.laminas.dev/t/whats-your-opinion-on-a-factory-provider/104 "2017-05-08T13:07:24Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![exts](https://avatars.discourse-cdn.com/v4/letter/e/dec6dc/32.png) [@exts](https://discourse.laminas.dev/u/exts)\
**Post date:** [May 8, 2017, 1:07pm UTC](https://discourse.laminas.dev/t/whats-your-opinion-on-a-factory-provider/104/1 "2017-05-08T13:07:24Z")

</div>

I personally got tired of the multiple files that builds up when creating action factory files so I wrote a class called FactoryProvider.

```
namespace Core;

/**
 * Class FactoryProvider
 *
 * @package Core
 */
abstract class FactoryProvider
{
    /**
     * @var array
     */
    private $factories = [];

    /**
     * @return array
     */
    public function __invoke()
    {
        $this->init();

        return ['factories' => $this->factories];
    }

    /**
     * @param string $class
     * @param \Closure $closure
     */
    protected function register(string $class, \Closure $closure)
    {
        $this->factories[$class] = $closure;
    }

    abstract public function init();
}

```

I use pimple as a container, but I’m sure this could work for practically any other container. Purpose of this just makes maintaining factories simpler for instance:

```
class FactoryProvider extends \Core\FactoryProvider
{
    public function init()
    {
        $this->register(LoginAction::class, function(Container $container) {
            $input = $container->has(Input::class) ? $container->get(Input::class) : null;

            $router = $container->has(RouterInterface::class)
                ? $container->get(RouterInterface::class) : null;

            $template = $container->has(TemplateRendererInterface::class)
                ? $container->get(TemplateRendererInterface::class) : null;

            $entity_manager = $container->has(EntityManager::class)
                ? $container->get(EntityManager::class) : null;

            $session = $container->has(Session::class)
                ? $container->get(Session::class) : null;

            $user_login_service = new UserLoginService($input, $entity_manager, $session);

            return new LoginAction($input, $router, $template, $user_login_service, $session);
        });
    }
}

```

Now not only in my user module can I keep track of all my user action factories in one file, but there aren’t 4 individual files that clogs up my folder.

Similar to ConfigProvider I just added it to the `ConfigAggregator`, but I had to add my own check in the container.php file for it to actually register.

How do you feel if expressive implemented something like this in the core framework?

---

<div class="post-metadata">

**Author:** ![belgattitude](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/belgattitude/32/241_2.png) [@belgattitude](https://discourse.laminas.dev/u/belgattitude)\
**Post date:** [May 8, 2017, 3:00pm UTC](https://discourse.laminas.dev/t/whats-your-opinion-on-a-factory-provider/104/2 "2017-05-08T15:00:33Z")

</div>

Hey @exts,

Nice, I agree with the fact that factory boilerplate can become quickly huge and It’s good to think about it.

But I’m less sure with your proposal. Personally, it’s gonna move the problem from ‘multiple files’ to ‘one big file’…

I guess you know about it, but if you use `zend-servicemanager : "^3.2"`, one solution could be to use the [ReflectionBasedAbstractFactory](https://docs.zendframework.com/zend-servicemanager/reflection-abstract-factory/) (_or eventually [ConfigAbstractFactory](https://docs.zendframework.com/zend-servicemanager/config-abstract-factory/)_)

When registering your dependencies, you’ll end up doing:

```php
use Zend\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory;

return [
  'abstract_factories' => [
    ReflectionBasedAbstractFactory::class,
  ],
  'factories' => [
    LoginAction::class => ReflectionBasedAbstractFactory::class
  ],
]

```

_(\*) the same idea can be written for pimple as well_

Of course, there is a some drawbacks for this approach:

- Not all classes can be instanciated based on reflection (types, circular deps).
- While reflection is good for prototyping it is not ideal for production (of course depend what you do)

Basically the performance problem could be tackled by tooling… (Naïve) examples could be, generating the factories when `zend-config-aggregator` creates the cache, or a specific command line tool that parse all references to `ReflectionBasedAbstractFactory` and generate the factories in a dedicated directory… (just some free thoughts, they might be harmful also…).

For my part I’ll continue writing factories, sometimes grouping pretty same actions under a common interface, i.e: `TheAlwaysSameActionConstructorInterface::__construct(Template, Router)` and load them with a unique factory.

But thank you for popping out with this issue. I had similar questions.

I would love to hear what others think, there can be other solutions I’m not aware of ?

---

<div class="post-metadata">

**Author:** ![exts](https://avatars.discourse-cdn.com/v4/letter/e/dec6dc/32.png) [@exts](https://discourse.laminas.dev/u/exts)\
**Post date:** [May 8, 2017, 4:59pm UTC](https://discourse.laminas.dev/t/whats-your-opinion-on-a-factory-provider/104/3 "2017-05-08T16:59:44Z")

</div>

Yeah I know about it, but I don’t use that as my service locator (I use `Pimple\Container`). So that’s a problem solved w/ zend’s service locator, but even then it’s not recommended outside of rapid prototyping.

Maybe even implement something like [Auryn](https://github.com/rdlowrey/auryn)

---

<div class="post-metadata">

**Author:** ![belgattitude](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/belgattitude/32/241_2.png) [@belgattitude](https://discourse.laminas.dev/u/belgattitude)\
**Post date:** [May 9, 2017, 3:47pm UTC](https://discourse.laminas.dev/t/whats-your-opinion-on-a-factory-provider/104/4 "2017-05-09T15:47:34Z")

</div>

Thanks I didn’t know about Auryn… not sure if it does not rely on reflection though.

BTW: Would be nice to have a benchmark with reflection…

---

<div class="post-metadata">

**Author:** ![matthew](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/matthew/32/14_2.png) [@matthew](https://discourse.laminas.dev/u/matthew)\
**Post date:** [May 15, 2017, 8:19pm UTC](https://discourse.laminas.dev/t/whats-your-opinion-on-a-factory-provider/104/5 "2017-05-15T20:19:45Z")

</div>

One huge drawback to this: the `factories` key becomes part of configuration, which, when using `ConfigAggregator`, we attempt to cache when in production. The issue that arises is that closures cannot be cached safely, due to how PHP serializes them. As such, the syntax you have above could potentially break the application.

One additional thing for you to research are [service providers](https://github.com/container-interop/service-provider). These are being proposed by the container-interop group, the same folks who brought us PSR-11, and is an attempt to help address this sort of thing… to an extent. You still end up writing classes or closures, but it provides an easy way to register factories for your PSR-11 container.

If the main problem you face is that you do not want to write classes, try looking into abstract factories or using the second argument passed to factories (the `$requestedName`); these can be used to re-use logic when the construction of multiple classes follows the same pattern, using the same arguments.
