Quantcast

ServiceManagerAwareInterface vs. ServiceLocatorAwareInterface

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

ServiceManagerAwareInterface vs. ServiceLocatorAwareInterface

demiankatz

According to the documentation here:

 

http://packages.zendframework.com/docs/latest/manual/en/zend.service-manager.quick-start.html#zend.service-manager.quick-start.examples.service-manager-aware

 

“By default, the Zend Framework MVC registers an initializer that will inject the ServiceManager instance into any class implementing Zend\ServiceManager\ServiceManagerAwareInterface. The default controller implementations implement this interface, as do a small number of other objects.”

 

However, this does not seem to be true (at least in beta5).  I was unable to get access to the ServiceManager by implementing ServiceManagerAwareInterface in my controller, and searching through the code base, I don’t see any default controller implementations using this interface.

 

Digging deeper into the code, I figured out that implementing ServiceLocatorAwareInterface instead of ServiceManagerAwareInterface does give my controllers access to the ServiceManager.

 

So what’s going on?  Is the documentation wrong?  Is the code in flux?  What is the distinction between these two interfaces?

 

And on a more general level, what is the best practice for injecting services into controllers?  My situation (probably a common one) is that my module is bootstrapping some resources that the controllers will need to use.  I just need a simple, lightweight way to access these resources.  Using the service manager is easy enough (now that I can access it), but if there is a better way, I’d love to see some examples.

 

thanks,

Demian

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: ServiceManagerAwareInterface vs. ServiceLocatorAwareInterface

weierophinney
Administrator
-- Demian Katz <[hidden email]> wrote
(on Tuesday, 10 July 2012, 07:48 PM +0000):

> According to the documentation here:
>
> http://packages.zendframework.com/docs/latest/manual/en/
> zend.service-manager.quick-start.html#
> zend.service-manager.quick-start.examples.service-manager-aware
>
>  
>
> “By default, the Zend Framework MVC registers an initializer that will inject
> the ServiceManager instance into any class implementing Zend\ServiceManager\
> ServiceManagerAwareInterface. The default controller implementations implement
> this interface, as do a small number of other objects.”

Ug -- should be ServiceLocatorAwareInterface, and setServiceLocator
should typehint on ServiceLocatorInterface. This was changed right after
beta4, but we clearly didn't update the docs with this information.


> However, this does not seem to be true (at least in beta5).  I was unable to
> get access to the ServiceManager by implementing ServiceManagerAwareInterface
> in my controller, and searching through the code base, I don’t see any default
> controller implementations using this interface.
>
> Digging deeper into the code, I figured out that implementing
> ServiceLocatorAwareInterface instead of ServiceManagerAwareInterface does give
> my controllers access to the ServiceManager.
>
> So what’s going on?  Is the documentation wrong?  Is the code in flux?  What is
> the distinction between these two interfaces?

The appropriate interface is ServiceLocatorAwareInterface. The reason
being is that this allows providing an alternate ServiceLocatorInterface
implementation -- ServiceManagerAwareInterface requires that you extend
ServiceManager, which kind of defeats the point of having an interface.

This was simply an oversight in beta4, which was corrected right after
release (and included in beta5).

> And on a more general level, what is the best practice for injecting services
> into controllers?  My situation (probably a common one) is that my module is
> bootstrapping some resources that the controllers will need to use.  I just
> need a simple, lightweight way to access these resources.  Using the service
> manager is easy enough (now that I can access it), but if there is a better
> way, I’d love to see some examples.

I typically create factories for these situations. The factories can
either be classes implementing Zend\ServiceManager\FactoryInterface, or
they can be a callback defined in your Module class:

    namespace My;

    class Module
    {
        public function getControllerConfiguration()
        {
            return array('factories' => array(
                'My\World' => function ($sm) {
                    $db   = $sm->get('Zend\Db\Adapter\Adapter');
                    $auth = $sm->get('Zend\Authentication\AuthenticationService');
                   
                    $controller = new My\Controller\WorldController($db);
                    $controller->setAuthentication($auth);
                    return $controller;
                },
            ));
        }
    }

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: ServiceManagerAwareInterface vs. ServiceLocatorAwareInterface

demiankatz
> Ug -- should be ServiceLocatorAwareInterface, and setServiceLocator
> should typehint on ServiceLocatorInterface. This was changed right after
> beta4, but we clearly didn't update the docs with this information.

Okay, that makes sense.  Well, at least it's easier to fix docs after a release than to fix a problem in the release itself!  If it would be helpful for me to open a ticket about this, let me know -- but otherwise I'll assume you've got it under control.

> The appropriate interface is ServiceLocatorAwareInterface. The reason
> being is that this allows providing an alternate ServiceLocatorInterface
> implementation -- ServiceManagerAwareInterface requires that you extend
> ServiceManager, which kind of defeats the point of having an interface.

I see that ServiceManagerAwareInterface is still being used in a couple of places.  I'm guessing this is probably intentional, since those places seem to be specifically related to the ServiceManager rather than generic implementations of the ServiceLocatorInterface.  However, I also notice that there are no comments at all in the file defining the ServiceManagerAwareInterface.  Assuming that the interface doesn't need to be completely removed after beta5, would it make sense to add some notes there explaining the specific use cases for that interface and pointing to ServiceLocatorAwareInterface as the more commonly useful generic case?

> I typically create factories for these situations. The factories can
> either be classes implementing Zend\ServiceManager\FactoryInterface, or
> they can be a callback defined in your Module class:

Thanks for the suggestion -- I'll give it a try!

- Demian
Loading...