How to use Dependency Injection container when I have a variable non-static parameter that I need to supply?
What I want in my code is this:
$staff = $container->get(Staff::class);
What I have now is this:
$staff = new Staff("my_great_username");
Note that username can change and is supplied at run-time.
I cannot seem to put Staff into my DI Container, because there is no way to specify a variable parameter there.
My Problem is ...
I am using Factory-based container, namely Zend\ServiceManager\ServiceManager.This is a factory that I use to hide instantiation details:
class StaffFactory
{
function __invoke(ContainerInterface $container): Staff
{
/*
* I do not seem to know how to get my username here
* nor if it is the place to do so here
*/
$staff = new Staff(????????);
return $staff;
}
}
The way I set up the container in my config is this:
'factories' => [
Staff::class => StaffFactory::class
]
Note: even though the parameter is a "variable", I want Staff to be immutable. Namely, once it is created, it stays that way. So I do not particularly wish to make a setter method for the username as that will imply that the class is mutable, when it is not.
What do you suggest?
My problem was that I had a variable parameter that was being passed to the constructor of my
Staffclass.The solution is to create a
StaffCreatorclass that does not have variable parameters in its constructor, and then write aStaffCreator::createmethod, which takes the variable parameter. Then, instead of injectingStaffinto whatever class whereStaffis needed, injectStaffCreatorinstead, and then use it to create aStaffinstance.i.e.
with credit to Steve
Note: You can create and add
Interfacesto the above code to make DI reusable. i.e.StaffCreatorInterface,StaffInterface. In my case I kept it simple, as I do not (yet) have a strong use case for reuse of the interface.