Php 在自己的可重用库中提供依赖项注入 背景
我正在编写一些可重用库,其中包含的类很少。 其中一个需要有依赖关系,因为一些更复杂的逻辑,我想把这个类的责任委托给其他地方(另一个类) 目标 我不想创建一个bundle,例如Symfony bundle,它可以处理依赖项注入,并提供一种简单的方法将其与客户端代码集成。 我的目标是提供可重用和独立于框架的解决方案 补充资料 我正在使用,并且我已经阅读了有关DI容器的信息,如。 有一个PHPDI的应用程序示例,但它不符合我的要求 例子 库代码片段Php 在自己的可重用库中提供依赖项注入 背景,php,dependency-injection,composer-php,Php,Dependency Injection,Composer Php,我正在编写一些可重用库,其中包含的类很少。 其中一个需要有依赖关系,因为一些更复杂的逻辑,我想把这个类的责任委托给其他地方(另一个类) 目标 我不想创建一个bundle,例如Symfony bundle,它可以处理依赖项注入,并提供一种简单的方法将其与客户端代码集成。 我的目标是提供可重用和独立于框架的解决方案 补充资料 我正在使用,并且我已经阅读了有关DI容器的信息,如。 有一个PHPDI的应用程序示例,但它不符合我的要求 例子 库代码片段 <?php class W3CAnalyze
<?php
class W3CAnalyzer implements WebStandardAnalyzer
{
private $httpClient;
public function __construct(HttpClient $httpClient)
{
$this->httpClient = $httpClient;
}
public function analyze(string $url): WC3AnalysisMetaData
{
$siteContent = $this->httpClient->getContent($url);
//further logic there
}
}
在客户机项目中,程序员将注册W3CAnalyzer
,以便使用其DI配置将其注入控制器中作为WebStandardAnalyzer
(如何注入并不重要)
问题
如果我在我的库内部使用一些DI配置和容器,我如何将此配置与客户机代码集成,这样就有可能注册库类,并且它的所有依赖关系都将得到解决?
我还不知道如何在我的库中组织DI(这实际上是问题的第一部分),我想以某种方式使用上面提到的PHPDI库
总而言之,如何在非框架可重用库中组织DI,以便库可以在每个其他项目中使用(无论使用哪个框架),并且它(该库)的依赖关系也将在该项目的运行时得到解决
谢谢大家!
class W3CAnalyzerFactory
{
public function build()
{
$Subject = new W3CAnalyzer(new HttpClient);
return $Subject
}
}
以上是我如何利用工厂模式,并取得了巨大成功。如果new HttpClient
不足以容纳您的代码(也就是说,它也需要构建),请执行以下操作:
class HttpClientFactory
{
public function build()
{
//modify this to actually construct the HttpClient object, with
//constructor and/or setter injections
$Subject = new HttpClient();
return $Subject
}
}
$WebStandardController = new WebStandardController(
(new W3CAnalyzerFactory())
->build()
);
然后,您的W3CAnalyzerFactory
将如下所示:
class W3CAnalyzerFactory
{
public function build()
{
$Subject = new W3CAnalyzer(
(new HttpClientFactory)
->build()
);
return $Subject
}
}
然后,使用您的库的用户可以执行以下操作:
class HttpClientFactory
{
public function build()
{
//modify this to actually construct the HttpClient object, with
//constructor and/or setter injections
$Subject = new HttpClient();
return $Subject
}
}
$WebStandardController = new WebStandardController(
(new W3CAnalyzerFactory())
->build()
);
或者,他们希望使用自己的DI设置。正如您所说,它们如何注入并不重要,只是它们可以使用W3CAnalyzerFactory
类,然后一切都准备就绪
提示:对于我的库和/或应用程序中的所有对象,我总是创建一个factory类,即使没有注入任何内容。一开始感觉很冗长,但有几个好处
HttpClient
),使它现在确实需要注入一些东西,那么使用HttpClientFactory
的所有工作都已经完成了,您不需要用(new HttpClientFactory)->build()
替换所有新的HttpClient()
行新的HttpClient
还是(新的HttpClientFactory)->build()
?不用想,只要使用工厂就可以了。)旁注:我将对象分配给
$Subject
,然后返回$Subject
一个单独的行,而不是只执行返回新内容…
,原因是我倾向于选择setter注入,这意味着我需要在构建对象后对其执行操作。不过,您要做最适合您的库和/或应用程序的事情。选择单词“subject”作为变量名是因为在我的单元测试中调用我的对象来表示“subject Under Test”。这些对象没有经过测试,所以我只是将它们命名为$Subject
,以获得一个很好的一致性名称,帮助我轻松地看到正在构造的对象是什么。同样,我的这个习惯完全是可以选择的。@RyanVincent我已经提供了一些额外的解释。依赖注入是一个原则。您的类WebStandardController
使用它。依赖项注入容器不需要使用DI。这只是一种使用单个调用创建对象及其依赖项的方便方法。@axiac和依赖项将自动解析?你读过我的帖子吗?DIC会自动解决依赖关系吗?我不这么认为;它需要配置。您的库是否导出了如此多的类,以至于需要一个DIC容器来构建它们?一次或几次还不够吗?如果你想让你的库的用户注入他们自己的HttpClient
实现,那么库中嵌入的DIC就会妨碍你。它需要配置——这就是重点和问题所在。如何使此配置与不同的框架兼容,或者与仅使用composer的普通PHP项目兼容,这是我的问题。我不明白工厂在我的情况下会如何帮助我(我知道ofc工厂和工厂方法模式是什么)。你能举个例子吗?那太好了。