I have written a custom service for my module. This service provides public static functions which should validate a given token.
Now i want to implement another public static function which checks if an Doctrine-Entity exists or not. For this case i need the object-manager or the service-locator in my service.
class ApiService
{
const KEY_LENGTH = 10;
const USE_NUMBERS = true;
const USE_CHARS = true;
public static function isValid($apiKey) {
$isValid = false;
# more code tbd
$isValid = self::exists($apiKey);
return $isValid;
}
public static function exists($apiKey) {
# Insert Object-Manager here
$validator = new \DoctrineModule\Validator\ObjectExists(array(
'object_repository' => $objectManager->getRepository('Application\Entity\User'),
'fields' => array('email')
));
}
}
Is it "best-practice" to implement my functions as public static and call them as static methods?
What is the best practice to inject the object-manager into my
doesEntityExist()
function?
Personally, I'd make the service a 'service' and put it in the ServiceManager. In addition I'd consider refactoring the code. Right now you have a dependency on the ObjectExists validator, which in turn depends on and entity repository, and that depends on the entity manager. It would be much simpler to compose the validator outside the service and inject it from a factory. That way, if you ever need to use a different validator, you just hand it a different one.
In Module.php create the service as a factory method, or better still as a factory class, but that's left as an exercise for you :)
Now if you need a different EntityManager, a different Entity repository, or even a whole different validator you only need to change a couple of lines above rather than having to delve into your services code.
The best approach would be to completely remove the static methods from your class here. ZF2 makes it really easy to fetch services by their name, so you shouldn't really need static methods for such a use case.
First of all, clean up your service:
Now define a factory for it:
Then map the service name to the factory (usually in your module):
NOTE: you may want to simply use a closure instead of defining a separate factory class, but having factory classes gives you a small performance boost when you're not using the service. Also, using a closure in configuration means you cannot cache the merged configuration, so consider using the method suggested here.
Here's an example without the factory class (again, consider using the approach explained above):
Now you can use the service in your controllers:
You can also retrieve it wherever you have the service manager:
As an additional suggestion, consider simplifying your service. Since
isValid
is already a method of your validator, you could simply return the validator itself (hereby using the closure method for simplicity):