ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

php – Laravel的容器绑定机制有何不同?

2019-06-11 12:26:51  阅读:246  来源: 互联网

标签:php design-patterns ioc-container laravel


我正在看Laravel的service container docs,特别是绑定部分.

有什么区别,什么时候应该使用每种类型的绑定?文件提到:

>简单绑定
> Singleton绑定
>实例绑定
>原始绑定
>接口绑定

解决方法:

首先,让我们看看它到底是什么:

IoC container is a component that knows how instances are created. It also knows of all their underlying dependencies and how to resolve them.

容器关于实例创建和依赖关系解析的知识可能由程序员指导.这就是为什么Laravel的容器为我和你提供各种绑定API的原因.

“解决出容器”是您经常阅读/听到的短语.这意味着您可以根据之前给她的[可选]指导告诉容器为您制作一些东西.

在继续阅读有关绑定之前,我强烈建议您阅读以下答案:
What is Laravel IoC Container in simple words?

简单的绑定

app()->bind(DatabaseWriter::class, function ($app) {
    return new DatabaseWriter(
        $app->make(DatabaseAdapterInterface)
    );
});

你对容器说,当你想要解析DatabaseWriter类的一个实例时,按照这个逻辑,我刚刚在闭包中告诉你,我知道的更好.每次要解决该类时,都必须遵循此并向我提供一个新实例.

您始终使用此类绑定.您正在为容器提供有关如何为您制作物品的小食谱.

单身绑定

与简单绑定相同,有一个明显的区别.你告诉容器我在整个应用程序中只需要一个这个类的实例.第一次解析类时,请遵循我传递给您的闭包中的逻辑,但请确保您每隔一段时间只返回一个实例来解决它.向我提供您允许的唯一实例.

这是一个单身人士吧?解析单例绑定后,将在后续调用容器时返回相同的对象实例.

显然,当您想要使用Singleton模式时,可以使用这种类型的绑定.这些日子很少见.

实例绑定

这就像为容器做一个忙.你没有告诉她如何实例化某个类,你自己做,只是给她实例.她为你拿着它,然后在随后的容器调用中返回它.

当你进行单元测试时,它特别方便.如果将模拟实例绑定到某个类的容器,则对app() – > make()的所有后续调用将为您返回该模拟.所以当你使用实际的类时,你实际上是在整个应用程序中注入一个类模拟.

class QuestionsControllerTest extends TestCase 
{  
    public function testQuestionListing()
    {
        $questionMock = Mockery::mock('Question')
           ->shouldReceive('latest')
           ->once()
           ->getMock();

        // You're telling the container that everytime anyone
        // wants a Question instance, give them this mock I just
        // gave you.
        $this->app->instance('Question', $this->questionMock);

        // whatever...
    }
}

原始绑定

Laravel的容器为您提供了一个DSL,告诉她如何解析基元.你说当BillingController类需要一个$taxRate变量且它没有被传递时,给它0.2.这就像设置远处的默认值!

app()->when('App\Http\Controllers\BillingController')
     ->needs('$taxRate')
     ->give(.2);

用例可能很少见,但偶尔也可能需要它们.这个例子可能更有感觉:

app()->when('App\Http\Controllers\CustomerController')
    ->needs('$customers')
    ->give(function() {
        return Customer::paying();
    });

接口绑定

当您想要将接口绑定到具体实现时,可以使用它.

在阅读了有关SOLID的十几篇文章以及如何成为更好的程序员之后,您决定遵循依赖性倒置原则,而不依赖于具体实例,您依赖于抽象.

毕竟,这是一个很好的做法,在Laravel内外.

class DatabaseWriter {

    protected $db;

    // Any concrete implementation of this interface will do
    // Now, that I depend on this DatabaseAdapterInterface contract,
    // I can work with MySQL, MongoDB and WhatevaDB! Awesome!
    public function __construct(DatabaseAdapterInterface $db)
    {
        $this->db = $db;
    }

    public function write()
    {
        $this->db->query('...');
    }

}

如果没有Laravel的容器,首先需要创建DatabaseAdapterInterface的具体实现,并将其传递给DatabaseWriter的构造函数,以便能够实例化它:

$dbWriter = new DatabaseWriter(new MongodbAdapter)

如果MongodbAdapter有自己的依赖项,你可能会在这里结束:

// Looks familiar, right? 
// These are those recipes you used to give to Laravel container 
// through simple binding. 
$dbWriter = new DatabaseWriter(new MongodbAdapter(new MongodbConnection))

但是在Laravel的聚会中,你告诉她当有人要求具体实现DatabaseAdapterInterface时,不要再问他们并给他们一个MongodbAdapter:

app()->bind(DatabaseAdapterInterface::class, MongodbAdapter::class)

然后你继续从容器中解析出一个DatabaseWriter实例,就像老板一样:

$dbWriter = app()->make(DatabaseWriter::class)

更简单,更清洁,对吧?你删除所有明显的混乱,并将其移动到其他地方.您的AppServiceProvider也许.

好的,让我们看看她在这种情况下的工作方式.首先,她探测DatabaseWriter是否存在可能的依赖关系(通过reflection),发现它需要一个DatabaseAdapterInterface.检查她的笔记本,回忆说你告诉她MongodbAdapter是该界面的具体实现.创建一个并将其交给DatabaseWriter.

如果你坚持依赖倒置原则,几乎所有时间都使用这些类型的绑定.

好的,喋喋不休,让我们看看她是如何工作的:
https://github.com/laravel/framework/blob/5.3/src/Illuminate/Container/Container.php#L627

标签:php,design-patterns,ioc-container,laravel
来源: https://codeday.me/bug/20190611/1218506.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有