Php 何时在控制器内实例化一个新类,何时将该类作为依赖项注入?

Php 何时在控制器内实例化一个新类,何时将该类作为依赖项注入?,php,oop,dependency-injection,instantiation,Php,Oop,Dependency Injection,Instantiation,何时使用new在控制器内创建任何类,何时将该类注入控制器 例如,假设我有一个AnnotationBuilder类(它通过读取域实体中的注释来构建Zend\Form对象) 我可以在我的控制器中这样调用它: $form = (new AnnotationBuilder())->createForm(MyForm::class); 或者,我可以将AnnotationBuilder的实例传递到我的控制器中,并按如下方式调用它: $form = $this->annotationBuilde

何时使用
new
在控制器内创建任何类,何时将该类注入控制器

例如,假设我有一个
AnnotationBuilder
类(它通过读取域实体中的注释来构建
Zend\Form
对象)

我可以在我的控制器中这样调用它:

$form = (new AnnotationBuilder())->createForm(MyForm::class);
或者,我可以将
AnnotationBuilder
的实例传递到我的控制器中,并按如下方式调用它:

$form = $this->annotationBuilder->createForm(MyForm::class);
或者,如果我将
AnnotationBuilder
直接传递给该方法,我可以使用:

$form = $annotationBuilder->createForm(MyForm::class);
对此有什么指导方针吗?例如,在阅读有关依赖项注入的内容时,我可以大胆猜测,我的任何和所有依赖项都必须声明,并且由于
AnnotationBuilder
是构建表单所需的一部分,因此我可能可以将其注入控制器的构造函数中。或者作为setter方法

还有别的课吗?目前,在我现有的控制器中,我可以计算出大约6名新的操作员。我是否会盲目地重构它们以将其全部传递给控制器


在控制器内使用
新建
创建一些东西是否可以接受?

这取决于模型层的复杂程度。对于
AnnotationBuilder
,我肯定会将其作为依赖项传递,但不一定在控制器中传递。我不是Zend用户,也不知道它实际上做了什么,但这听起来像是“输出内容”,应该放在视图实例中(如果您有这些实例,而不仅仅是愚蠢的模板)

通常,我会编写代码,其中控制器只与来自模型层的各种服务交互。由于这些服务在每个运行时都是单一的,所以最好将它们作为依赖项传递

但在每个服务中,我会处理各种实体(域对象)。而且,虽然每个运行时只有一个
身份验证
服务,但它可能由多个
身份
(或者可能是
帐户
)实体管理。这些“重复实例”我不会作为依赖项传递。相反,我要么使用
new
操作符,要么使用某个工厂创建它们(这将是一个依赖项,用于单元测试目的)


我希望这会有帮助。

我不认为因为有人这么说就遵循规则是个好主意。有理由这样做很重要

注射和恢复之间有什么关系

我发现它更重要的场景是在单元测试中。你要对你的控制器进行单元测试吗?如果是,您希望模拟
AnnotationBuilder
,因为它会影响性能还是出于其他原因


除了测试用例之外,拥有这种具体的依赖关系也是一个问题,或者你应该注入它的抽象?对于最后一个问题,一般来说,我看不出控制器依赖于混凝土的问题,因为它只是应用程序的基础结构入口点。

将实例传递到类中可以更好地测试类,允许您创建无法直接测试的类的模拟。我会考虑<值> > <代码>可接受的值对象。作为补充,永远不要盲目重构,除非您有300%的测试覆盖率。e、 g.对象是通过引用传递的,如果容器在多次调用中重用同一对象,您可能会遇到一些脏状态。Zend\Form涵盖了所有内容->我使用AnnotationBuilder构造表单(它使用我的域对象创建表单对象本身),然后用值填充表单(有时从数据库中提取),然后我将完成的表单传递给视图,视图负责将其呈现为HTML。换句话说,AnnotationBuilder是一个临时对象。它用于构建某些内容,然后被丢弃。它就像一个排序工厂。我可以将其完全移出控制器,在其他位置构建表单,然后将表单注入c遥控器。。。