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
Staff
class.The solution is to create a
StaffCreator
class that does not have variable parameters in its constructor, and then write aStaffCreator::create
method, which takes the variable parameter. Then, instead of injectingStaff
into whatever class whereStaff
is needed, injectStaffCreator
instead, and then use it to create aStaff
instance.i.e.
with credit to Steve
Note: You can create and add
Interfaces
to 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.