From Apprentice To Artisan 翻譯 03

上一篇php

The IoC Container 控制反轉容器

Basic Binding 基礎綁定

Now that we've learned about dependency injection, let's explore inversion of control containers. IoC containers make managing your class dependencies much more convenient, and Laravel ships with a very powerful container. The IoC container is the certral piece of the Laravel framework, and it is what allows all of the framework's jcomponents jto work together. In fact, the Laravel Application class extends the Container class!git

咱們已經學習了依賴注入,接下來我們一塊兒來探索「控制反轉容器」(IoC)。 IoC容器可使你更容易管理依賴注入,Laravel框架擁有一個很強大的IoC容器。Laravel的核心就是這個IoC容器,這個IoC容器使得框架各個組件能很好的在一塊兒工做。事實上Laravel的Application類就是繼承自Container類!github

IoC Container 控制反轉容器

Inversion of control containers make dependency injection more convenient. How to resolve a given class or interface is defined once in the container, which manages resolving and injecting those objects throughout your application.api

控制反轉容器使得依賴注入更方便。當一個類或接口在容器裏定義之後,如何處理它們——如何在應用中管理、注入這些對象?閉包

In a Laravel application, the IoC container can be accessed via the App facade. The container has a variety of methods, but we'll start with the most basic. Let's continue to use our BillerInterface and BillingNotifierInterface from the previous chapter, and assume that our application is using Stripe to process payments. We can bind the Stripe implementation of the interface to the container like this:app

在Laravel應用裏,你能夠經過App來訪問控制反轉容器。容器有不少方法,不過咱們從最基礎的開始。讓咱們繼續使用上一章寫的BillerInterfaceBillingNotifierInterface,且假設咱們使用了Stripe來進行支付操做。咱們能夠將Stripe的支付實現綁定到容器裏,就像這樣:框架

<!-- lang: php -->
App::bind('BillerInterface', function()
{
    return new StripeBiller(App::make('BillingNotifierInterface'));
});

Notice that within our BillingInterface resolver, we also resolve a BillingNotifierInterface implementation. Let's define that binding as well:ide

注意在咱們處理BillingInterface時,咱們額外須要一個BillingNotifierInterface的實現,也就是再來一個bind:函數

<!-- lang: php -->
App::bind('BillingNotifierInterface', function()
{
    return new EmailBillingNotifier;
});

So, as you can see, the container is a place to store Closures that resolve various classes. Once a class has been registered with the container, we can easily resolve it from anywhere in our application. We can even resolve other container bindings within a resolver.學習

如你所見, 這個容器就是個用來存儲各類綁定的地方(譯者注:這麼理解簡單點。再扯匿名函數、閉包就扯遠了。)。一旦一個類在容器裏綁定了之後,咱們能夠很容易的在應用的任何位置調用它。咱們甚至能夠在bind函數內寫另外的bind。

Have Acne?

The Laravel IoC container is a drop-in replacement for the Pimple IoC container by Fabien Potencier. So, if you're already using Pimple on a project, feel free to upgrade to the Illuminate Container component for a few more features!

Laravel框架的Illuminate容器和另外一個名爲Pimple的IoC容器是可替換的。因此若是你以前用的是Pimple,你盡能夠大膽的升級爲Illuminate Container,後者還有更多新功能!

Once we're using the container, we can switch interface implementations with a single line change. For example, consider the following:

一旦咱們使用了容器,切換接口的實現就是一行代碼的事兒。 好比考慮如下代碼:

<!-- lang: php -->
class UserController extends BaseController{

    public function __construct(BillerInterface $biller)
    {
        $this->biller = $biller;
    }
}

When this controller is instantiated via the IoC container, the StripeBiller, which includes the EmailBillingNotifier, will be injected into the instance. Now, if we want to change our notifier implementation, we can simply change the binding to this:

當這個控制器通被容器實例化後,包含着EmailBillingNotifierStripeBiller會被注入到這個控制器中(譯者注:見上文的兩個bind)。若是咱們如今想要換一種提示方式,咱們能夠簡單的將代碼改成這樣:

<!-- lang: php -->
App::bind('BillingNotifierInterface', function()
{
    return new SmsBillingNotifier;
});

Now, it doesn't matter where the notifier is resolved in our application, we will now always get the SmsBillingNotifier implementation. Utilizing this architecture, our application can be rapidly shifted to new implementations of various services.

如今無論在應用的哪裏須要一個提示器,咱們總會獲得SmsBillingNotifier的對象。利用這種結構,咱們的應用能夠在不一樣的實現方式之間快速切換。

Being able to change implementations of an interface with a single line is amazingly powerful. For example, imagine we want to change our SMS service from a legacy provider to Twilio. We can develop a new Twilio implementation of the notifier and swap our binding. If we have problems with the transition to Twilio, we can quickly change back to the legacy provider by making a single IoC binding change. As you can see, the benefits of using dependency injection go beyond what is immediately obvious. Can you think of more benefits for using dependency injection and an IoC container?

只改一行就能切換代碼實現,這但是很厲害的能力。好比咱們想把短信服務從原來的提供商替換爲Twilio。咱們能夠開發一個新的Twilio的提示器類(譯者注:固然要繼承自BillingNotifierInterface)而後修改綁定語句。若是Twilio有任何閃失,咱們只需修改一行代碼就能夠快速的切換回原來的短信提供商。看到了吧,依賴注入的好處多得很呢。你能再想出幾個使用依賴注入和控制反轉容器的好處麼?

Sometimes you may wish to resolve only one instance of a given class throughout your entire application. This can be achieved via the singleton method on the container class:

想在應用中只實例化某類一次?沒問題,使用singleton方法吧:

<!-- lang: php -->
App::singleton('BillingNotifierInterface', function()
{
    return new SmsBillingNotifier;
});

Now, once the container has resolved the billing notifier once, it will continue to use that same instance for all subsequent requests for that interface.

這樣只要這個容器生成了這個提示器對象一次, 在接下來的生成請求中容器都只會提供這一樣的一個對象。

The instance method on the container is similar to singleton, however, you are able to pass an already existing object instance. The instance you give to the container will be used each time the container needs an instance of that class:

容器的instance方法和singleton方法很相似,區別是instance能夠綁定一個已經存在的對象。而後容器每次返回的都是這個對象了。

<!-- lang: php -->
$notifier = new SmsBillingNotifier;
App::instance('BillingNotifierInterface', $notifier);

Now that we're familiar with basic container resolution using Closures, let's dig into its most powerful feature: the ability to resolve class via reflection.

如今咱們熟悉了容器的基礎用法,讓咱們深刻發掘它更強大的功能:依靠反射來處理類和接口。

Stand Alone Container 容器獨立運行

Working on a project that isn't built on Laravel? You can still utilize Laravel's IoC container by installing the illuminate/container package via Composer!

你的項目沒有使用Laravel?但你依然可使用Laravel的IoC容器!只要用Composer安裝了illuminate/container包就能夠了。

下一篇

相關文章
相關標籤/搜索