Closed khuyennguyen7007 closed 5 years ago
If I understand your request correctly, then please have a look at method build
of the Zend\ServiceManager\ServiceManager
class. All informations can be found in the documentation (direct link).
Sorry but it seem like your docs is not what I need. In factory, I can not determine the context where build method invoked (eg: what controller, what module,...). Morever, it seem like factory just allow pass an array options. I need automatic dependency injection on constructor like this:
__construct(ClassOne $one, ClassTwo $two) {}
I need automatic dependency injection on constructor…
Then look at the reflection based factory: https://docs.zendframework.com/zend-servicemanager/reflection-abstract-factory/
Like i said, i need two things:
@khuyennguyen7007 I will provide a code example.
@khuyennguyen7007
The context is provided by the parameter $requestedName
.
The example shows the usage of the parameter in the factory for the controllers.
// Factory for controllers
$controllerFactory = static function (
Psr\Container\ContainerInterface $container,
$requestedName,
array $options = null
) {
switch ($requestedName) {
case UserController::class:
$options = [
'parameter_1',
'parameter_2',
];
break;
case PostController::class:
$options = [
'parameter_1',
'parameter_2',
'parameter_3',
];
break;
default:
$options = [];
break;
}
$container->build(SearchManager::class, $options);
};
// Factory for search-manager
$searchManagerFactory = static function (
Psr\Container\ContainerInterface $container,
$requestedName,
array $options = null
) {
return new class (...$options) {
public function __construct($param1 = null, $param2 = null, $param3 = null)
{
var_dump($param1);
var_dump($param2);
var_dump($param3);
}
};
};
// Service manager
$serviceManager = new Zend\ServiceManager\ServiceManager(
[
'factories' => [
SearchManager::class => $searchManagerFactory,
UserController::class => $controllerFactory,
PostController::class => $controllerFactory,
],
]
);
// Get controllers
$serviceManager->get(UserController::class); // string(11) "parameter_1", string(11) "parameter_2", NULL
$serviceManager->get(PostController::class); // string(11) "parameter_1", string(11) "parameter_2", string(11) "parameter_3"
Please do not use this code in production, it's far away from perfect and it's only illustrative material for this issue report.
Thank you very much for your sample code. But i'm still stuck in this:
$serviceManager->get(UserController::class)
not return object instance, it's return null
value.ReflectionBasedAbstractFactory
. Eg:
class Service {}
class UserController { public function __construct(SearchManager $searchManager, Service $service) { var_dump($service); } }
When `$serviceManager->get(UserController::class);`, it's will automatic injected dependencies and build `SearchManager` as above.
@khuyennguyen7007
$serviceManager->get(UserController::class)
not return object instance, it's return null value.
There is missing return
statement before $container->build(SearchManager::class, $options);
in the first function provided by @froschdesign.
How to combined it with
ReflectionBasedAbstractFactory
. Eg...
I guess you want to use: https://github.com/zendframework/zend-di
@khuyennguyen7007
$serviceManager->get(UserController::class)
not return object instance, it's return null value.
Right, but this is not needed in this example. Only the output is interesting. (See the notice under the code example.)
Sorry but it's very weird to me. I'm still not understand.
$serviceManager->get(UserController::class)
must be return UserController
instance for using in my case. Why is it not needed?
class Service {}
class UserController { public function __construct(SearchManager $searchManager, Service $service) { var_dump($searchManager); } }
`$searchManager` will be null in params.
@khuyennguyen7007
$serviceManager->get(UserController::class)
must be returnUserController
instance for using in my case. Why is it not needed?
It‘s not needed here on GitHub as example to illustrate the workflow. In real application you need return $requestedName(…)
. The important part of my example is the output from var_dump
.
@khuyennguyen7007 My example was created for running without extra classes. Maybe that was not clear enough. Sorry for that!
In a real application you must change this line in the controller factory from:
$container->build(SearchManager::class, $options);
to
return new $requestedName($container->build(SearchManager::class, $options));
I must rewrite code in factory
The same with your factory: if ($requestedName == IndexController::class)
Btw. this won't work in your factory: return $container->get($requestedName);
– the service-manager will call the factory again.
@khuyennguyen7007 I think you found a solution for your application. Can we close this request?
If you have further questions, please use the official forum.
I'm using zend service manager to manage my dependencies. In this case, I want to inject params to constructor base on context. Specifically, I have an
SearchManager
class, if inApplication\User\Index
, it will be injected with 2 params, but inApplication\Post\Index
, it will be injected 3 params.