作为开发人员,我们一直在尝试找到新的方法来编写设计和清洁代码,并使用新样式,使用设计模式以及尝试新的健壮框架。在本文中,我们将通过Laravel的IOC组件探索依赖性注入设计模式,并查看如何改善我们的设计。
钥匙要点依赖注入是敏捷体系结构的关键要素。
让我们看看一个示例:
如果要测试或维护此类,则必须访问真实数据库并进行一些查询。为了避免必须这样做,并从剩下的类中
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>
将组件注入班级时,您可以使用以下三个选项之一:> 构造器注入
设置器注入
<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(控制倒置)不需要使用依赖注入,但是它可以帮助您有效地管理依赖项。
>
倒置控制当您要求一个对象时,Laravel IOC以某种方式与解决依赖关系的方式很特别:
>我们将使用一个简单的示例,我们将在本文中进行改进。
SimpleAuth类具有Filesessessorage的依赖性,因此我们的代码可能看起来像:
这是这样做的经典方式,让我们从使用构造函数注入开始。
现在我们创建我们的对象:
<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>
由于应用程序类扩展了容器类,因此您可以始终通过应用程序外观访问容器。
<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>
假设我们要将会话存储切换到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>
>
因此,我们可以抽象我们的存储实现:
这样,我们就可以实现并要求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,但是如果您的项目越来越大,则必须使用服务提供商。测试:
经常询问有关Laravel IOC- 刚刚进行测试时,您需要考虑使用PHP Artisan Tinker,它非常强大,并且可以增加Laravel测试工作流程。
反射API:
- PHP反射API非常强大,如果您想了解laravel ioc,您需要熟悉反射API,请务必检查本教程以获取更多信息。
结论>
>一如既往,了解某些内容的最佳方法是检查源代码。 Laravel IOC只是一个文件,不应该花您很长时间来完成所有功能。您想进一步了解Laravel IOC或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中文网其他相关文章!