How to correctly declare service factories on modules?

Hi everyone,

I’m trying laminas after a while away from the framework ecosystem, and I’m having a bad time trying to expose a service from a module.

I am trying to get a service instance on a controller factory via $container->get(Application\Repository\GameMatchRepositoryInterface::class::class); and I’m getting the common error of

Unable to resolve service Application\Repository\GameMatchRepositoryInterface::class to a factory; are you certain you provided it during configuration?

I have the following on module\Application\config\module.config.php (which I created based on the tutorial.
May you guys see if I’m missing something basic? I tried a shameful amount of different approaches like InvokableFactory, or implementing getServiceConfig on Module.php, and so on…
Also, my factory implements \Laminas\ServiceManager\Factory\FactoryInterface!

return [
    'service_manager' => [
        'aliases' => [
            Application\Repository\GameMatchRepositoryInterface::class => Application\Repository\GameMatchRepository::class,
        ],
        'factories' => [
            Application\Repository\GameMatchRepository::class => Application\Repository\GameMatchRepositoryFactory::class
        ]
    ]
    ...
];

I’m on PHP 7.4.15 with these deps:

"require": {
        "php": "^7.3",
        "laminas/laminas-component-installer": "^1.0 || ^2.1",
        "laminas/laminas-development-mode": "^3.2",
        "laminas/laminas-mvc": "^3.1.1",
        "laminas/laminas-cache": "^2.9.0",
        "laminas/laminas-db": "^2.10.0",
        "laminas/laminas-mvc-form": "^1.0",
        "laminas/laminas-json": "^3.1.2",
        "laminas/laminas-log": "^2.11",
        "laminas/laminas-mvc-console": "^1.2.0",
        "laminas/laminas-mvc-i18n": "^1.1.1",
        "laminas/laminas-mvc-plugins": "^1.0.1",
        "laminas/laminas-psr7bridge": "^1.2.0",
        "laminas/laminas-session": "^2.9.1",
        "laminas/laminas-di": "^3.1.1",
        "ramsey/uuid": "^4.1",
        "photogabble/draughts": "dev-master"
},

Oh, I forgot to mention that by adding the same array part on global.php, it works… Really strange

Hello and welcome to our forums! :smiley:

Is this an copy-paste error or why is ::class duplicated here?

Your module class should look like this:

namespace Application;

class Module
{
    public function getConfig()
    {
        return include __DIR__ . '/../config/module.config.php';
    }
}

…nothing more. Compare with the description in the tutorial: Introducing the Blog Module - tutorials - Laminas Docs

Oops, copy-paste error.

I remembered I have it on Github!
The controller factory: https://github.com/renanliberato/checkers/blob/master/module/Application/src/Controller/IndexControllerFactory.php#L19
The service globally declared on application.config.php (which is working, even thought I’d like to use it in module.config.php): https://github.com/renanliberato/checkers/blob/master/config/application.config.php#L63

If I try to copy paste this ‘service_manager’ subarray from application.config.php to Application/config/module.config.php, it does not work…

Please check that the cache is disabled for development.

Oh my God,
The factory was not being resolved due to a mistype (and lack of knowledge about the difference) when setting up the service config.
Instead of doing this:

'factories' => [
    Application\Repository\GameMatchRepositoryInterface::class => Application\Repository\GameMatchRepositoryFactory::class
]

I should have done this:

'factories' => [
    \Application\Repository\GameMatchRepositoryInterface::class => \Application\Repository\GameMatchRepositoryFactory::class
]

Or of course, import the damn class on the top of config\module.config.php

It worked on application.config.php because it was not already on “Application” namespace.

Thanks for all the help, and I hope it helps someone later :sweat_smile: