助力软件开发企业降本增效 PHP / java源码系统,只需一次付费,代码终身使用! 广告
### **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! > ### **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. > 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](http://Stripe.com) implementation of the interface to the container like this: ~~~ <?php <!-- 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: ~~~ <?php <!-- 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. > **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](https://github.com/fabpot/pimple) on a project, feel free to upgrade to the [Illuminate Container](https://github.com/jilluminate/container) component for a few more features! > Once we're using the container, we can switch interface implementations with a single line change. For example, consider the following: ~~~ <?php <!-- 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: ~~~ <?php <!-- 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. 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? 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: ~~~ <?php <!-- 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: ~~~ <?php <!-- 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! >