| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -45,6 +45,13 @@ class Container implements ArrayAccess, ContainerContract { | |||
| 45 | 45 | */ | |
| 46 | 46 | protected $aliases = array(); | |
| 47 | 47 | ||
| 48 | + /** | ||
| 49 | + * The extension closures for services. | ||
| 50 | + * | ||
| 51 | + * @var array | ||
| 52 | + */ | ||
| 53 | + protected $extenders = []; | ||
| 54 | + | ||
| 48 | 55 | /** | |
| 49 | 56 | * All of the registered tags. | |
| 50 | 57 | * | |
@@ -302,11 +309,6 @@ public function bindShared($abstract, Closure $closure) | |||
| 302 | 309 | */ | |
| 303 | 310 | public function extend($abstract, Closure $closure) | |
| 304 | 311 | { | |
| 305 | - if ( ! isset($this->bindings[$abstract])) | ||
| 306 | - { | ||
| 307 | - throw new \InvalidArgumentException("Type {$abstract} is not bound."); | ||
| 308 | - } | ||
| 309 | - | ||
| 310 | 312 | if (isset($this->instances[$abstract])) | |
| 311 | 313 | { | |
| 312 | 314 | $this->instances[$abstract] = $closure($this->instances[$abstract], $this); | |
@@ -315,32 +317,10 @@ public function extend($abstract, Closure $closure) | |||
| 315 | 317 | } | |
| 316 | 318 | else | |
| 317 | 319 | { | |
| 318 | - $extender = $this->getExtender($abstract, $closure); | ||
| 319 | - | ||
| 320 | - $this->bind($abstract, $extender, $this->isShared($abstract)); | ||
| 320 | + $this->extenders[$abstract][] = $closure; | ||
| 321 | 321 | } | |
| 322 | 322 | } | |
| 323 | 323 | ||
| 324 | - /** | ||
| 325 | - * Get an extender Closure for resolving a type. | ||
| 326 | - * | ||
| 327 | - * @param string $abstract | ||
| 328 | - * @param \Closure $closure | ||
| 329 | - * @return \Closure | ||
| 330 | - */ | ||
| 331 | - protected function getExtender($abstract, Closure $closure) | ||
| 332 | - { | ||
| 333 | - // To "extend" a binding, we will grab the old "resolver" Closure and pass it | ||
| 334 | - // into a new one. The old resolver will be called first and the result is | ||
| 335 | - // handed off to the "new" resolver, along with this container instance. | ||
| 336 | - $resolver = $this->bindings[$abstract]['concrete']; | ||
| 337 | - | ||
| 338 | - return function($container) use ($resolver, $closure) | ||
| 339 | - { | ||
| 340 | - return $closure($resolver($container), $container); | ||
| 341 | - }; | ||
| 342 | - } | ||
| 343 | - | ||
| 344 | 324 | /** | |
| 345 | 325 | * Register an existing instance as shared in the container. | |
| 346 | 326 | * | |
@@ -672,6 +652,14 @@ public function make($abstract, $parameters = array()) | |||
| 672 | 652 | $object = $this->make($concrete, $parameters); | |
| 673 | 653 | } | |
| 674 | 654 | ||
| 655 | + // If we defined any extenders for this type, we'll need to spin through them | ||
| 656 | + // and apply them to the object being built. This allows for the extension | ||
| 657 | + // of services, such as changing configuration or decorating the object. | ||
| 658 | + foreach ($this->getExtenders($abstract) as $extender) | ||
| 659 | + { | ||
| 660 | + $object = $extender($object, $this); | ||
| 661 | + } | ||
| 662 | + | ||
| 675 | 663 | // If the requested type is registered as a singleton we'll want to cache off | |
| 676 | 664 | // the instances in "memory" so we can return it later without creating an | |
| 677 | 665 | // entirely new instance of an object on each subsequent request for it. | |
@@ -705,7 +693,8 @@ protected function getConcrete($abstract) | |||
| 705 | 693 | // since the container should be able to resolve concretes automatically. | |
| 706 | 694 | if ( ! isset($this->bindings[$abstract])) | |
| 707 | 695 | { | |
| 708 | - if ($this->missingLeadingSlash($abstract) && isset($this->bindings['\\'.$abstract])) | ||
| 696 | + if ($this->missingLeadingSlash($abstract) && | ||
| 697 | + isset($this->bindings['\\'.$abstract])) | ||
| 709 | 698 | { | |
| 710 | 699 | $abstract = '\\'.$abstract; | |
| 711 | 700 | } | |
@@ -741,6 +730,22 @@ protected function missingLeadingSlash($abstract) | |||
| 741 | 730 | return is_string($abstract) && strpos($abstract, '\\') !== 0; | |
| 742 | 731 | } | |
| 743 | 732 | ||
| 733 | + /** | ||
| 734 | + * Get the extender callbacks for a given type. | ||
| 735 | + * | ||
| 736 | + * @param string $abstract | ||
| 737 | + * @return array | ||
| 738 | + */ | ||
| 739 | + protected function getExtenders($abstract) | ||
| 740 | + { | ||
| 741 | + if (isset($this->extenders[$abstract])) | ||
| 742 | + { | ||
| 743 | + return $this->extenders[$abstract]; | ||
| 744 | + } | ||
| 745 | + | ||
| 746 | + return []; | ||
| 747 | + } | ||
| 748 | + | ||
| 744 | 749 | /** | |
| 745 | 750 | * Instantiate a concrete instance of the given type. | |
| 746 | 751 | * | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -518,29 +518,6 @@ public function bound($abstract) | |||
| 518 | 518 | return isset($this->deferredServices[$abstract]) || parent::bound($abstract); | |
| 519 | 519 | } | |
| 520 | 520 | ||
| 521 | - /** | ||
| 522 | - * "Extend" an abstract type in the container. | ||
| 523 | - * | ||
| 524 | - * (Overriding Container::extend) | ||
| 525 | - * | ||
| 526 | - * @param string $abstract | ||
| 527 | - * @param \Closure $closure | ||
| 528 | - * @return void | ||
| 529 | - * | ||
| 530 | - * @throws \InvalidArgumentException | ||
| 531 | - */ | ||
| 532 | - public function extend($abstract, Closure $closure) | ||
| 533 | - { | ||
| 534 | - $abstract = $this->getAlias($abstract); | ||
| 535 | - | ||
| 536 | - if (isset($this->deferredServices[$abstract])) | ||
| 537 | - { | ||
| 538 | - $this->loadDeferredProvider($abstract); | ||
| 539 | - } | ||
| 540 | - | ||
| 541 | - return parent::extend($abstract, $closure); | ||
| 542 | - } | ||
| 543 | - | ||
| 544 | 521 | /** | |
| 545 | 522 | * Determine if the application has booted. | |
| 546 | 523 | * | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -214,6 +214,19 @@ public function testExtendIsLazyInitialized() | |||
| 214 | 214 | } | |
| 215 | 215 | ||
| 216 | 216 | ||
| 217 | + public function testExtendCanBeCalledBeforeBind() | ||
| 218 | + { | ||
| 219 | + $container = new Container; | ||
| 220 | + $container->extend('foo', function($old, $container) | ||
| 221 | + { | ||
| 222 | + return $old.'bar'; | ||
| 223 | + }); | ||
| 224 | + $container['foo'] = 'foo'; | ||
| 225 | + | ||
| 226 | + $this->assertEquals('foobar', $container->make('foo')); | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + | ||
| 217 | 230 | public function testParametersCanBePassedThroughToClosure() | |
| 218 | 231 | { | |
| 219 | 232 | $container = new Container; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -86,7 +86,7 @@ public function testDeferredServicesAreLazilyInitialized() | |||
| 86 | 86 | $this->assertTrue($app->bound('foo')); | |
| 87 | 87 | $this->assertFalse(ApplicationDeferredServiceProviderStub::$initialized); | |
| 88 | 88 | $app->extend('foo', function($instance, $container) { return $instance.'bar'; }); | |
| 89 | - $this->assertTrue(ApplicationDeferredServiceProviderStub::$initialized); | ||
| 89 | + $this->assertFalse(ApplicationDeferredServiceProviderStub::$initialized); | ||
| 90 | 90 | $this->assertEquals('foobar', $app->make('foo')); | |
| 91 | 91 | $this->assertTrue(ApplicationDeferredServiceProviderStub::$initialized); | |
| 92 | 92 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments