Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 部分依赖注入_Php_Dependency Injection_Php Di - Fatal编程技术网

Php 部分依赖注入

Php 部分依赖注入,php,dependency-injection,php-di,Php,Dependency Injection,Php Di,在MVC上下文中,我有一个依赖于服务的控制器,而服务又依赖于数据源(在特定情况下,是从第三方API获取数据的客户端) 为了在测试时使用模拟数据源实例化服务,服务的构造函数需要一个数据源。 控制器也是如此,其构造函数需要一个服务 当创建一个控制器时,我也想给它传递一个请求对象,因为我更喜欢这样 新控制器(请求、服务)。操作名称 对此 新控制器(服务)。操作\u名称(请求) 在不使用任何容器进行依赖注入的情况下实现这一点是微不足道的 我不明白的是如何使用 我的目标是让容器将服务注入控制器,同时自己将

在MVC上下文中,我有一个依赖于服务的控制器,而服务又依赖于数据源(在特定情况下,是从第三方API获取数据的客户端)

为了在测试时使用模拟数据源实例化服务,服务的构造函数需要一个数据源。 控制器也是如此,其构造函数需要一个服务

当创建一个控制器时,我也想给它传递一个请求对象,因为我更喜欢这样

新控制器(请求、服务)。操作名称

对此

新控制器(服务)。操作\u名称(请求)

在不使用任何容器进行依赖注入的情况下实现这一点是微不足道的

我不明白的是如何使用

我的目标是让容器将服务注入控制器,同时自己将请求对象传递给控制器

更新1

这是我的应用程序控制器

namespace DEC;


class ApplicationController {

    private $service;
    private $request;

    public function __construct(Foo $service, $request) {
        $this->service= $service;
        $this->request = $request;
    }


    public function index() {
        $out = $this->service->foo();
        $out .= $this->request->method();
        return $out;
    }

}
傅如下

namespace DEC;

class Foo {

    public function __construct() {
    }

    public function foo() {
        return "FOO";
    }
}
这是我的要求

namespace DEC;

class Foo {

    public function __construct() {
    }

    public function foo() {
        return "FOO";
    }
}
这是我试图让DI按照我的意愿工作:

$container = ContainerBuilder::buildDevContainer();
$response = $container->call([ApplicationController::class, 'index'], [
            'request' => new Request('GET')
]);
echo $response;
这是我得到的错误:

Entry "DEC\ApplicationController" cannot be resolved: Parameter $request of __construct() has no value defined or guessable
Full definition:
Object (
    class = DEC\ApplicationController
    scope = singleton
    lazy = false
    __construct(
        $service = get(DEC\Foo)
        $request = #UNDEFINED#
    )
)
N.B.:如果我在构造函数中键入提示请求和/或切换参数顺序,则错误保持不变

查看错误,我推断Matthew Napoli提出的::call()解决方案在我仅使用服务实例化控制器并将请求作为action方法的参数传递时有效

这是否意味着我不能依靠容器进行“部分”注射

更新2


对于此更新中描述的解决方案,请查看我自己对问题的回答

不太清楚您尝试了什么,但这应该调用操作方法并将请求传递给它(并解决控制器及其所有依赖项):


阅读有关调用()的更多信息:

关于请求:

不要键入$request参数:

public function __construct($request, /*...*/) {}
或为其键入一个RequestInterface:

public function __construct(RequestInterface $request, /*...*/) {}
在这两种情况下,DIC都无法自动创建请求实例。然后你可以自己注射

关于服务:

键入一个具体的提示,如“服务”。然后,DIC将自动创建一个服务实例及其所有依赖项(数据源)

或者使用接口(如“ServiceInterface”)键入hint it,并使用PHP定义中的别名在DIC中为其设置一个条目。大概是这样的:

return [
    'ServiceInterface' => DI\get('<NAMESPACE-TO>\Service'),
];
返回[
'ServiceInterface'=>DI\get('\Service'),
];
见:

PHP-DI的“限制”

PHP-DI“PHP定义-别名”位于


希望这能有所帮助。

在请求控制器之前,我通过在容器中设置请求来做到这一点:

$container->set('DEC\Request', new Request('GET'));
$controller = $container->get('DEC\ApplicationController');
$response = $controller->index();

您想使用PHPDI的原因是什么?它确实使用反射(慢)。你只需要在你的项目中加入一些第三方的“黑魔法”。你到底能省多少打字费?只有我的IMHO。@E_p没有性能损失,所有内容都被缓存。如果您不喜欢反射,也可以禁用它:我的代码库很小,我不希望出现可测量的性能问题。我选择了PHPDI,因为它在GitHub上有将近1K的订户,并且是积极维护的?
$container->set('DEC\Request', new Request('GET'));
$controller = $container->get('DEC\ApplicationController');
$response = $controller->index();