首页 > 后端开发 > php教程 > Laravel的依赖注入

Laravel的依赖注入

Lisa Kudrow
发布: 2025-02-21 10:28:11
原创
449 人浏览过

Laravel的依赖注入

作为开发人员,我们一直在尝试找到新的方法来编写设计和清洁代码,并使用新样式,使用设计模式以及尝试新的健壮框架。在本文中,我们将通过Laravel的IOC组件探索依赖性注入设计模式,并查看如何改善我们的设计。

钥匙要点

    依赖注入(DI)是一种设计模式,可以使硬编码依赖关系解耦,从而使代码更加灵活,可重复使用且易于测试。在Laravel的IOC(控制倒置)中,这是通过将所需的依赖项传递到外部对象而不是使对象创建依赖关系或要求工厂对象为其制作一个的对象来实现的。
  • > Laravel的IOC容器是管理类依赖性的强大工具。它控制了如何解决和创建不同对象。当一类具有依赖性时,容器会在类称为“自动接线”的过程实例化时自动注入它们。
  • >
  • >使用绑定方法可以将服务绑定到Laravel的IOC容器。此方法接受两个参数:解决服务时将使用的类或接口名称,以及返回类实例的闭合。关闭将接收容器实例,使您可以解决实例化类所需的任何其他依赖项。
  • Laravel的IOC容器还允许接口绑定。这使您可以将接口绑定到给定的实现。然后,每当请求接口时,容器都会注入限制的实现。这进一步增强了代码的灵活性和可重复性。
  • 依赖注入
依赖注入是由马丁·福勒(Martin Fowler)创造的术语,这是将组件注入应用程序的行为。就像沃德·坎宁安(Ward Cunningham)一样:

依赖注入是敏捷体系结构的关键要素。

让我们看看一个示例:

如果要测试或维护此类,则必须访问真实数据库并进行一些查询。为了避免必须这样做,并从剩下的类中

decouple
<span>class UserProvider{
</span>    <span>protected $connection;
</span>    
    <span>public function __construct(){
</span>        <span>$this->connection = new Connection;
</span>    <span>}
</span>    
    <span>public function retrieveByCredentials( array $credentials ){
</span>        <span>$user = $this->connection
</span>                        <span>->where( 'email', $credentials['email'])
</span>                        <span>->where( 'password', $credentials['password'])
</span>                        <span>->first();
</span>                        
        <span>return $user;
</span>    <span>}
</span><span>}</span>
登录后复制
登录后复制
登录后复制
,您有三个选项之一可以注入连接类,而无需直接直接使用它。

将组件注入班级时,您可以使用以下三个选项之一:> 构造器注入

设置器注入

同样,我们可以使用Setter方法注入我们的依赖性:>
<span>class UserProvider{
</span>    <span>protected $connection;
</span>    
    <span>public function __construct( Connection $con ){
</span>        <span>$this->connection = $con;
</span>    <span>}
</span>    <span>...</span>
登录后复制
登录后复制
登录后复制

接口注入

当类实现我们的界面时,我们定义了要解决依赖项的注入连接方法。
<span>class UserProvider{
</span>    <span>protected $connection;
</span>    <span>public function __construct(){
</span>        <span>...
</span>    <span>}
</span>    
    <span>public function setConnection( Connection $con ){
</span>        <span>$this->connection = $con;
</span>    <span>}
</span>    <span>...</span>
登录后复制
登录后复制
登录后复制

优点

现在,在测试我们的课程时,我们可以模拟依赖项类并将其作为参数传递。每个班级都必须专注于特定任务,并且不应关心解决其依赖性。这样,您将拥有更好的专注和可维护的应用程序。

如果您想进一步了解DI,Alejandro Gervassio在本系列中广泛而专业地介绍了它,请务必阅读这些文章。现在,IOC呢? IOC(控制倒置)不需要使用依赖注入,但是它可以帮助您有效地管理依赖项。

>

倒置控制

IOC是一个简单的组件,可以使解决依赖性更加方便。您将您的对象描述到容器中,每次解决一类时,依赖项会自动注入。

laravel ioc

当您要求一个对象时,Laravel IOC以某种方式与解决依赖关系的方式很特别:

>我们将使用一个简单的示例,我们将在本文中进行改进。

SimpleAuth类具有Filesessessorage的依赖性,因此我们的代码可能看起来像:>

Laravel的依赖注入这是这样做的经典方式,让我们从使用构造函数注入开始。

现在我们创建我们的对象:

<span>class UserProvider{
</span>    <span>protected $connection;
</span>    
    <span>public function __construct(){
</span>        <span>$this->connection = new Connection;
</span>    <span>}
</span>    
    <span>public function retrieveByCredentials( array $credentials ){
</span>        <span>$user = $this->connection
</span>                        <span>->where( 'email', $credentials['email'])
</span>                        <span>->where( 'password', $credentials['password'])
</span>                        <span>->first();
</span>                        
        <span>return $user;
</span>    <span>}
</span><span>}</span>
登录后复制
登录后复制
登录后复制
现在,我想使用Laravel IOC来管理所有这些。>

由于应用程序类扩展了容器类,因此您可以始终通过应用程序外观访问容器。

<span>class UserProvider{
</span>    <span>protected $connection;
</span>    
    <span>public function __construct( Connection $con ){
</span>        <span>$this->connection = $con;
</span>    <span>}
</span>    <span>...</span>
登录后复制
登录后复制
登录后复制

bind方法的第一个参数是一个唯一的ID来绑定到容器中,第二个是每次解决文件essionStorage类时要执行的回调函数,我们还可以传递代表类名称的字符串,如我们所见下一个。

<span>class UserProvider{
</span>    <span>protected $connection;
</span>    <span>public function __construct(){
</span>        <span>...
</span>    <span>}
</span>    
    <span>public function setConnection( Connection $con ){
</span>        <span>$this->connection = $con;
</span>    <span>}
</span>    <span>...</span>
登录后复制
登录后复制
登录后复制
注意:如果您检查Laravel包,则有时会将绑定如(view,view.finder ..)。

假设我们要将会话存储切换到MySQL,我们的课程应与:

相似:

>现在我们已经改变了依赖关系,我们需要更改简单构造函数并将新对象绑定到容器!
<span>interface ConnectionInjector{
</span>    <span>public function injectConnection( Connection $con );
</span><span>}
</span>
<span>class UserProvider implements ConnectionInjector{
</span>    <span>protected $connection;
</span>    
    <span>public function __construct(){
</span>        <span>...
</span>    <span>}
</span>    
    <span>public function injectConnection( Connection $con ){
</span>        <span>$this->connection = $con;
</span>    <span>}
</span><span>}</span>
登录后复制
高级模块不应取决于低级模块。两个

应该取决于抽象。

抽象不应取决于细节。详细信息应取决于

在抽象上。

Robert C. Martin

<span>class FileSessionStorage{
</span>  <span>public function __construct(){
</span>    <span>session_start();
</span>  <span>}
</span>  
  <span>public function get( $key ){
</span>    <span>return $_SESSION[$key];
</span>  <span>}
</span>
  <span>public function set( $key, $value ){
</span>    <span>$_SESSION[$key] = $value;
</span>  <span>}
</span><span>}
</span>
<span>class SimpleAuth{
</span>  <span>protected $session;
</span>
  <span>public function __construct(){
</span>    <span>$this->session = new FileSessionStorage;
</span>  <span>}
</span><span>}
</span>
<span>//creating a SimpleAuth
</span><span>$auth = new SimpleAuth();</span>
登录后复制
>我们的SimpleAuth类不应该关注我们的存储方式,而应该更多地专注于仅消费服务。

>

因此,我们可以抽象我们的存储实现:


这样,我们就可以实现并要求sessionStorage接口的实例:>

<span>class UserProvider{
</span>    <span>protected $connection;
</span>    
    <span>public function __construct(){
</span>        <span>$this->connection = new Connection;
</span>    <span>}
</span>    
    <span>public function retrieveByCredentials( array $credentials ){
</span>        <span>$user = $this->connection
</span>                        <span>->where( 'email', $credentials['email'])
</span>                        <span>->where( 'password', $credentials['password'])
</span>                        <span>->first();
</span>                        
        <span>return $user;
</span>    <span>}
</span><span>}</span>
登录后复制
登录后复制
登录后复制

>如果我们尝试使用App :: Make('SimpleAuth')通过容器解决简单的类,则容器将在尝试从绑定中解析类,然后倒退到反射方法并解决后,将抛出bindingResolutionException所有依赖项。

<span>class UserProvider{
</span>    <span>protected $connection;
</span>    
    <span>public function __construct( Connection $con ){
</span>        <span>$this->connection = $con;
</span>    <span>}
</span>    <span>...</span>
登录后复制
登录后复制
登录后复制

容器正在尝试实例化接口。我们可以通过为我们的界面创建特定的绑定来解决这一点。

>
<span>class UserProvider{
</span>    <span>protected $connection;
</span>    <span>public function __construct(){
</span>        <span>...
</span>    <span>}
</span>    
    <span>public function setConnection( Connection $con ){
</span>        <span>$this->connection = $con;
</span>    <span>}
</span>    <span>...</span>
登录后复制
登录后复制
登录后复制

现在,每次我们尝试通过容器解决接口时,我们都会获得一个mySQLSessionStorage实例。如果我们要切换我们的存储服务,我们可以更新绑定。

>

>注意:如果要查看类是绑定到容器的类别,您可以使用app :: bond('className')或使用app :: bindif('className')在绑定(如果hasn'hasn'的情况下)注册t已经注册了。

Laravel IOC还提供APP :: Singleton('className','Resolver')用于共享绑定。

您还可以使用app :: instance('className','instance')创建共享实例。
如果容器无法解决依赖关系,它将抛出反射exception,但是我们可以使用app :: resolvingany(closure)解决任何给定类型或作为后备的形式。>
>注意:如果您为给定类型注册解析器,也将调用解决方案方法,但是返回了绑定方法的值。>>>>>>

最终提示

在哪里存储绑定:

如果您只有一个小应用程序,则可以使用global/start.php,但是如果您的项目越来越大,则必须使用服务提供商。
    测试:
  • 刚刚进行测试时,您需要考虑使用PHP Artisan Tinker,它非常强大,并且可以增加Laravel测试工作流程。
  • 反射API:
  • PHP反射API非常强大,如果您想了解laravel ioc,您需要熟悉反射API,请务必检查本教程以获取更多信息。>
  • 结论

  • >一如既往,了解某些内容的最佳方法是检查源代码。 Laravel IOC只是一个文件,不应该花您很长时间来完成所有功能。您想进一步了解Laravel IOC或IOC吗?让我们知道!
经常询问有关Laravel IOC

中依赖注入的问题

>在Laravel的IOC中依赖注入的主要目的是什么?这意味着,您没有让您的对象创建依赖关系或要求工厂对象为其制作一个对象,而是将所需的依赖项传递到外部对象。这使您的代码更加灵活,可重复使用且更易于测试,因为您可以从类外部控制依赖项。

> Laravel的IOC容器如何工作?它控制了如何解决和创建不同对象。当类具有依赖性时,容器会在实例化时自动注入它们。这是通过称为“自动线”的过程完成的,容器会在其中检查类以自动确定依赖项。将服务绑定到Laravel的IOC容器,您可以使用绑定方法。此方法接受两个参数:解决服务时将使用的类或接口名称,以及返回类实例的闭合。闭合将接收容器实例,允许您解决实例化类所需的任何其他依赖。 Laravel的IOC容器中的Singleton在于如何管理实例。当您绑定服务时,每次您解决该服务时都会创建服务的新实例。另一方面,当您使用Singleton时,每次解决服务时都会返回相同的实例。

>

>我如何从Laravel的IOC容器中解析服务?从Laravel的IOC容器中,您可以使用Make方法。此方法接受服务的名称以解决其参数。如果该服务已绑定到容器,它将返回服务的实例,其所有依赖项会自动注入。

>

>依赖量注射如何改善Laravel的测试?通过使您的代码更加灵活和脱钩来测试Laravel。这意味着您可以在测试过程中轻松地将依赖关系与模拟对象交换。这使得隔离测试的代码并控制测试环境变得更加容易。

我可以在Laravel的IOC容器中使用接口绑定吗? 。这使您可以将接口绑定到给定的实现。然后,每当请求接口时,容器都会注入限制的实现。

>

> laravel的IOC容器如何处理自动分辨率?

laravel的IOC容器的IOC容器可以通过使用反射来检查依赖项来处理自动分辨率一堂课。当您尝试解决一堂课时,容器将自动构建和注入类所需的所有依赖项。

>

> Laravel的IOC容器中的服务提供商是什么?容器是一种在单个位置分组相关的IOC注册的方法。它们是配置您的应用程序的中心地点。每个Laravel应用程序都包含许多服务提供商的核心服务。

>如何在Laravel的IOC容器中注册服务提供商?

>在Laravel的IOC容器中注册服务提供商,您可以将其添加到config/app.php配置文件中的提供商数组中。一旦注册了服务提供商,该应用程序被引导时将由Laravel引导。

以上是Laravel的依赖注入的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板