Customer service and service factory not registering in ZF3

1k views Asked by At

For some reason, I don't think that my 'service_manager' config is being read properly. This is mostly pretty much a brand-new skeleton checkout. Maybe a days work.

I did another one recently and tried comparing. I can't figure out where I went wrong.

Under the anonymous function pointed to by Controller\DbBuilderController::class => function(ContainerInterface $container, $requestedName) { the line $userService = $container->get(\Application\Service\UserService::class); causes an error: Unable to resolve service "Application\Service\UserService" to a factory; are you certain you provided it during configuration?

I have tried changing \Application\Service\UserService::class to short, silly, literal strings so I'm confident that the service is not being registered.

I'm not sure why that would happen. Any takers?

<?php
namespace Application;

use Zend\Mvc\Application;
use Zend\Mvc\Controller\LazyControllerAbstractFactory;
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;
use Interop\Container\ContainerInterface;

use Doctrine\ORM\Mapping\Driver\AnnotationDriver;

return [
    'service_manager' => [
        'factories' => [
            \Application\Service\UserService::class => \Application\Service\Factory\UserServiceFactory::class
        ],
    ],
    'doctrine' => [
        'driver' => [
            __NAMESPACE__ . '_driver' => [
                'class' => AnnotationDriver::class,
                'cache' => 'array',
                'paths' => [__DIR__ . '/../src/Entity']
            ],
            'orm_default' => [
                'drivers' => [
                    __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
                ]
            ]
        ]
    ],

    'router' => [
        'routes' => [
            'home' => [
                'type' => Literal::class,
                'options' => [
                    'route'    => '/',
                    'defaults' => [
                        'controller' => Controller\IndexController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
            'createUser' => [
                'type' => Segment::class,
                'options' => [
                    'route'    => '/createuser/:username/:password',
                    'defaults' => [
                        'controller' => Controller\DbBuilderController::class,
                        'action'     => 'createUser',
                        'username' => '',
                        'password' => ''
                    ],
                ],
            ],
            'importTrades' => [
                'type' => Literal::class,
                'options' => [
                    'route'    => '/importTrades',
                    'defaults' => [
                        'controller' => Controller\DbBuilderController::class,
                        'action'     => 'importTrades',
                    ],
                ],
            ],
            'createExchanges' => [
                'type' => Literal::class,
                'options' => [
                    'route'    => '/createExchanges',
                    'defaults' => [
                        'controller' => Controller\DbBuilderController::class,
                        'action'     => 'createExchanges',
                    ],
                ],
            ],

        ],
    ],
    'controllers' => [
        'factories' => [
            Controller\IndexController::class => InvokableFactory::class,
            Controller\DbBuilderController::class => function(ContainerInterface $container, $requestedName) {
                $entityManager = $container->get('doctrine.entitymanager.orm_default');
                $userService = $container->get(\Application\Service\UserService::class);
                return new Controller\DbBuilderController($entityManager, $userService);
            },
        ],

    ],

    'view_manager' => [
        'display_not_found_reason' => true,
        'display_exceptions'       => true,
        'doctype'                  => 'HTML5',
        'not_found_template'       => 'error/404',
        'exception_template'       => 'error/index',
        'template_map' => [
            'layout/layout'           => __DIR__ . '/../view/layout/layout.phtml',
            'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
            'error/404'               => __DIR__ . '/../view/error/404.phtml',
            'error/index'             => __DIR__ . '/../view/error/index.phtml',
        ],
        'template_path_stack' => [
            __DIR__ . '/../view',
        ],
    ],
    'strategies' => array(
        'ViewJsonStrategy',
    ),
];

The factory:

<?php

namespace Application\Service\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;

class UserServiceFactory implements FactoryInterface {

    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $entityManager = $container->get('doctrine.entitymanager.orm_default');

        $user = new \Application\Service\UserService($entityManager);
        return $user;
    }

}

The Service:

<?php

namespace Application\Service;

class UserService
{
    protected $entityManager;

    function __construct(\Doctrine\ORM\EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function createUser($username, $password)
    {
        $user = new \Application\Entity\User();
        $user->setUserKey($password);
        $user->setUserName($username);
        $user->setIsAdmin(true);

        $this->entityManager->persist($user);
        $this->entityManager->flush();

        return $user;
    }
}
1

There are 1 answers

0
avy On

Looking at the ZF3 service manager suggests it can't load the factory class, i.e. class_exists('Application\Service\Factory\UserServiceFactory') is failing.

Make sure the autoloader is registered for the Application namespace, either using the getAutoloaderConfig function in Module.php or by adding into the composer.json:

"autoload": {
    "psr-4": {
        "Application\\": "module/Application/src/"
    }
},

(obviously with the directory changed as necessary) then run composer update.

Maybe also check the directory structure containing UserServiceFactory for typos if you're using the Zend\Loader\StandardAutoloader.