← All changes
|
vendor/wpfluent/framework/src/WPFluent/Container/Container.php
+97
-53
1.21
→
2.1.0
View file →
| @@ -249,18 +249,20 @@ | ||
| 249 | 249 | public function bind($abstract, $concrete = null, $shared = false) |
| 250 | 250 | { |
| 251 | 251 | $this->dropStaleInstances($abstract); |
| 252 | 252 | |
| 253 | - // If no concrete type was given, we will simply set the concrete type to the | |
| 254 | - // abstract type. After that, the concrete type to be registered as shared | |
| 255 | - // without being forced to state their classes in both of the parameters. | |
| 253 | + // If no concrete type was given, we will simply set the concrete | |
| 254 | + // type to the abstract type. After that, the concrete type to | |
| 255 | + // be registered as shared without being forced to state | |
| 256 | + // their classes in both of the parameters. | |
| 256 | 257 | if (is_null($concrete)) { |
| 257 | 258 | $concrete = $abstract; |
| 258 | 259 | } |
| 259 | 260 | |
| 260 | - // If the factory is not a Closure, it means it is just a class name which is | |
| 261 | - // bound into this container to the abstract type and we will just wrap it | |
| 262 | - // up inside its own Closure to give us more convenience when extending. | |
| 261 | + // If the factory is not a Closure, it means it is just a class name | |
| 262 | + // which is bound into this container to the abstract type and we | |
| 263 | + // will just wrap it up inside its own Closure to give us more | |
| 264 | + // convenience when extending. | |
| 263 | 265 | if (! $concrete instanceof Closure) { |
| 264 | 266 | if (! is_string($concrete)) { |
| 265 | 267 | throw new TypeError(self::class.'::bind(): Argument #2 ($concrete) must be of type Closure|string|null'); |
| 266 | 268 | } |
| @@ -269,11 +271,12 @@ | ||
| 269 | 271 | } |
| 270 | 272 | |
| 271 | 273 | $this->bindings[$abstract] = compact('concrete', 'shared'); |
| 272 | 274 | |
| 273 | - // If the abstract type was already resolved in this container we'll fire the | |
| 274 | - // rebound listener so that any objects which have already gotten resolved | |
| 275 | - // can have their copy of the object updated via the listener callbacks. | |
| 275 | + // If the abstract type was already resolved in this container | |
| 276 | + // we'll fire the rebound listener so that any objects which | |
| 277 | + // have already gotten resolved can have their copy of the | |
| 278 | + // object updated via the listener callbacks. | |
| 276 | 279 | if ($this->resolved($abstract)) { |
| 277 | 280 | $this->rebound($abstract); |
| 278 | 281 | } |
| 279 | 282 | } |
| @@ -472,11 +475,12 @@ | ||
| 472 | 475 | $isBound = $this->bound($abstract); |
| 473 | 476 | |
| 474 | 477 | unset($this->aliases[$abstract]); |
| 475 | 478 | |
| 476 | - // We'll check to determine if this type has been bound before, and if it has | |
| 477 | - // we will fire the rebound callbacks registered with the container and it | |
| 478 | - // can be updated with consuming classes that have gotten resolved here. | |
| 479 | + // We'll check to determine if this type has been bound before, and | |
| 480 | + // if it has we will fire the rebound callbacks registered with | |
| 481 | + // the container and it can be updated with consuming classes | |
| 482 | + // that have gotten resolved here. | |
| 479 | 483 | $this->instances[$abstract] = $instance; |
| 480 | 484 | |
| 481 | 485 | if ($isBound) { |
| 482 | 486 | $this->rebound($abstract); |
| @@ -690,12 +694,35 @@ | ||
| 690 | 694 | * @throws \FluentBoards\Framework\Container\Contracts\BindingResolutionException |
| 691 | 695 | */ |
| 692 | 696 | public function make($abstract, array $parameters = []) |
| 693 | 697 | { |
| 694 | - return $this->resolve($abstract, $parameters); | |
| 698 | + try { | |
| 699 | + return $this->resolve($abstract, $parameters); | |
| 700 | + } catch (BindingResolutionException $e) { | |
| 701 | + if (class_exists($class = $this->retry($abstract))) { | |
| 702 | + return $this->make($class, $parameters); | |
| 703 | + } | |
| 704 | + | |
| 705 | + throw $e; | |
| 706 | + } | |
| 695 | 707 | } |
| 696 | 708 | |
| 697 | 709 | /** |
| 710 | + * Try to resolve the given service from the Framework context. | |
| 711 | + * | |
| 712 | + * @param string|null $module [description] | |
| 713 | + * @return string | |
| 714 | + */ | |
| 715 | + protected function retry($module) | |
| 716 | + { | |
| 717 | + $pieces = explode('\\', __NAMESPACE__); | |
| 718 | + array_pop($pieces); | |
| 719 | + $prefix = implode('\\', $pieces); | |
| 720 | + | |
| 721 | + return $prefix . '\\' . str_replace('.', '\\', $module); | |
| 722 | + } | |
| 723 | + | |
| 724 | + /** | |
| 698 | 725 | * {@inheritdoc} |
| 699 | 726 | * |
| 700 | 727 | * @return mixed |
| 701 | 728 | */ |
| @@ -726,11 +753,12 @@ | ||
| 726 | 753 | protected function resolve($abstract, $parameters = [], $raiseEvents = true) |
| 727 | 754 | { |
| 728 | 755 | $abstract = $this->getAlias($abstract); |
| 729 | 756 | |
| 730 | - // First we'll fire any event handlers which handle the "before" resolving of | |
| 731 | - // specific types. This gives some hooks the chance to add various extends | |
| 732 | - // calls to change the resolution of objects that they're interested in. | |
| 757 | + // First we'll fire any event handlers which handle the "before" | |
| 758 | + // resolving of specific types. This gives some hooks the | |
| 759 | + // chance to add various extends calls to change the | |
| 760 | + // resolution of objects that they're interested in. | |
| 733 | 761 | if ($raiseEvents) { |
| 734 | 762 | $this->fireBeforeResolvingCallbacks($abstract, $parameters); |
| 735 | 763 | } |
| 736 | 764 | |
| @@ -737,11 +765,13 @@ | ||
| 737 | 765 | $concrete = $this->getContextualConcrete($abstract); |
| 738 | 766 | |
| 739 | 767 | $needsContextualBuild = ! empty($parameters) || ! is_null($concrete); |
| 740 | 768 | |
| 741 | - // If an instance of the type is currently being managed as a singleton we'll | |
| 742 | - // just return an existing instance instead of instantiating new instances | |
| 743 | - // so the developer can keep using the same objects instance every time. | |
| 769 | + // If an instance of the type is currently being managed as a | |
| 770 | + // singleton we'll just return an existing instance | |
| 771 | + // instead of instantiating new instances so the | |
| 772 | + // developer can keep using the same objects | |
| 773 | + // instance every time. | |
| 744 | 774 | if (isset($this->instances[$abstract]) && ! $needsContextualBuild) { |
| 745 | 775 | return $this->instances[$abstract]; |
| 746 | 776 | } |
| 747 | 777 | |
| @@ -750,11 +780,12 @@ | ||
| 750 | 780 | if (is_null($concrete)) { |
| 751 | 781 | $concrete = $this->getConcrete($abstract); |
| 752 | 782 | } |
| 753 | 783 | |
| 754 | - // We're ready to instantiate an instance of the concrete type registered for | |
| 755 | - // the binding. This will instantiate the types, as well as resolve any of | |
| 756 | - // its "nested" dependencies recursively until all have gotten resolved. | |
| 784 | + // We're ready to instantiate an instance of the concrete type | |
| 785 | + // registered for the binding. This will instantiate the types, | |
| 786 | + // as well as resolve any of its "nested" dependencies | |
| 787 | + // recursively until all have gotten resolved. | |
| 757 | 788 | if ($this->isBuildable($concrete, $abstract)) { |
| 758 | 789 | $object = $this->build($concrete); |
| 759 | 790 | } else { |
| 760 | 791 | $object = $this->make($concrete); |
| @@ -759,18 +790,20 @@ | ||
| 759 | 790 | } else { |
| 760 | 791 | $object = $this->make($concrete); |
| 761 | 792 | } |
| 762 | 793 | |
| 763 | - // If we defined any extenders for this type, we'll need to spin through them | |
| 764 | - // and apply them to the object being built. This allows for the extension | |
| 765 | - // of services, such as changing configuration or decorating the object. | |
| 794 | + // If we defined any extenders for this type, we'll need to spin | |
| 795 | + // through them and apply them to the object being built. | |
| 796 | + // This allows for the extension of services, such as | |
| 797 | + // changing configuration or decorating the object. | |
| 766 | 798 | foreach ($this->getExtenders($abstract) as $extender) { |
| 767 | 799 | $object = $extender($object, $this); |
| 768 | 800 | } |
| 769 | 801 | |
| 770 | - // If the requested type is registered as a singleton we'll want to cache off | |
| 771 | - // the instances in "memory" so we can return it later without creating an | |
| 772 | - // entirely new instance of an object on each subsequent request for it. | |
| 802 | + // If the requested type is registered as a singleton we'll want to | |
| 803 | + // cache off the instances in "memory" so we can return it later | |
| 804 | + // without creating an entirely new instance of an object | |
| 805 | + // on each subsequent request for it. | |
| 773 | 806 | if ($this->isShared($abstract) && ! $needsContextualBuild) { |
| 774 | 807 | $this->instances[$abstract] = $object; |
| 775 | 808 | } |
| 776 | 809 | |
| @@ -777,11 +810,12 @@ | ||
| 777 | 810 | if ($raiseEvents) { |
| 778 | 811 | $this->fireResolvingCallbacks($abstract, $object); |
| 779 | 812 | } |
| 780 | 813 | |
| 781 | - // Before returning, we will also set the resolved flag to "true" and pop off | |
| 782 | - // the parameter overrides for this build. After those two things are done | |
| 783 | - // we will be ready to return back the fully constructed class instance. | |
| 814 | + // Before returning, we will also set the resolved flag to "true" | |
| 815 | + // and pop off the parameter overrides for this build. After | |
| 816 | + // those two things are done we will be ready to return | |
| 817 | + // back the fully constructed class instance. | |
| 784 | 818 | $this->resolved[$abstract] = true; |
| 785 | 819 | |
| 786 | 820 | array_pop($this->with); |
| 787 | 821 | |
| @@ -795,11 +829,12 @@ | ||
| 795 | 829 | * @return mixed |
| 796 | 830 | */ |
| 797 | 831 | protected function getConcrete($abstract) |
| 798 | 832 | { |
| 799 | - // If we don't have a registered resolver or concrete for the type, we'll just | |
| 800 | - // assume each type is a concrete name and will attempt to resolve it as is | |
| 801 | - // since the container should be able to resolve concretes automatically. | |
| 833 | + // If we don't have a registered resolver or concrete for the type, | |
| 834 | + // we'll just assume each type is a concrete name and will | |
| 835 | + // attempt to resolve it as is since the container should | |
| 836 | + // be able to resolve concretes automatically. | |
| 802 | 837 | if (isset($this->bindings[$abstract])) { |
| 803 | 838 | return $this->bindings[$abstract]['concrete']; |
| 804 | 839 | } |
| 805 | 840 | |
| @@ -817,11 +852,12 @@ | ||
| 817 | 852 | if (! is_null($binding = $this->findInContextualBindings($abstract))) { |
| 818 | 853 | return $binding; |
| 819 | 854 | } |
| 820 | 855 | |
| 821 | - // Next we need to see if a contextual binding might be bound under an alias of the | |
| 822 | - // given abstract type. So, we will need to check if any aliases exist with this | |
| 823 | - // type and then spin through them and check for contextual bindings on these. | |
| 856 | + // Next we need to see if a contextual binding might be bound under | |
| 857 | + // an alias of the given abstract type. So, we will need to check | |
| 858 | + // if any aliases exist with this type and then spin through | |
| 859 | + // them and check for contextual bindings on these. | |
| 824 | 860 | if (empty($this->abstractAliases[$abstract])) { |
| 825 | 861 | return; |
| 826 | 862 | } |
| 827 | 863 | |
| @@ -832,9 +868,10 @@ | ||
| 832 | 868 | } |
| 833 | 869 | } |
| 834 | 870 | |
| 835 | 871 | /** |
| 836 | - * Find the concrete binding for the given abstract in the contextual binding array. | |
| 872 | + * Find the concrete binding for the given abstract | |
| 873 | + * in the contextual binding array. | |
| 837 | 874 | * |
| 838 | 875 | * @param string|callable $abstract |
| 839 | 876 | * @return \Closure|string|null |
| 840 | 877 | */ |
| @@ -929,11 +966,12 @@ | ||
| 929 | 966 | { |
| 930 | 967 | $results = []; |
| 931 | 968 | |
| 932 | 969 | foreach ($dependencies as $dependency) { |
| 933 | - // If the dependency has an override for this particular build we will use | |
| 934 | - // that instead as the value. Otherwise, we will continue with this run | |
| 935 | - // of resolutions and let reflection attempt to determine the result. | |
| 970 | + // If the dependency has an override for this particular build | |
| 971 | + // we will use that instead as the value. Otherwise, we will | |
| 972 | + // continue with this run of resolutions and let reflection | |
| 973 | + // attempt to determine the result. | |
| 936 | 974 | if ($this->hasParameterOverride($dependency)) { |
| 937 | 975 | $results[] = $this->getParameterOverride($dependency); |
| 938 | 976 | |
| 939 | 977 | continue; |
| @@ -938,11 +976,12 @@ | ||
| 938 | 976 | |
| 939 | 977 | continue; |
| 940 | 978 | } |
| 941 | 979 | |
| 942 | - // If the class is null, it means the dependency is a string or some other | |
| 943 | - // primitive type which we can not resolve since it is not a class and | |
| 944 | - // we will just bomb out with an error since we have no-where to go. | |
| 980 | + // If the class is null, it means the dependency is a string or | |
| 981 | + // some other primitive type which we can not resolve since | |
| 982 | + // it is not a class and we will just bomb out with an | |
| 983 | + // error since we have no-where to go. | |
| 945 | 984 | $result = is_null(Util::getParameterClassName($dependency)) |
| 946 | 985 | ? $this->resolvePrimitive($dependency) |
| 947 | 986 | : $this->resolveClass($dependency); |
| 948 | 987 | |
| @@ -1026,11 +1065,12 @@ | ||
| 1026 | 1065 | ? $this->resolveVariadicClass($parameter) |
| 1027 | 1066 | : $this->make(Util::getParameterClassName($parameter)); |
| 1028 | 1067 | } |
| 1029 | 1068 | |
| 1030 | - // If we can not resolve the class instance, we will check to see if the value | |
| 1031 | - // is optional, and if it is we will return the optional parameter value as | |
| 1032 | - // the value of the dependency, similarly to how we do this with scalars. | |
| 1069 | + // If we can not resolve the class instance, we will check to see | |
| 1070 | + // if the value is optional, and if it is we will return the | |
| 1071 | + // optional parameter value as the value of the dependency, | |
| 1072 | + // similarly to how we do this with scalars. | |
| 1033 | 1073 | catch (BindingResolutionException $e) { |
| 1034 | 1074 | if ($parameter->isDefaultValueAvailable()) { |
| 1035 | 1075 | array_pop($this->with); |
| 1036 | 1076 | |
| @@ -1071,9 +1111,9 @@ | ||
| 1071 | 1111 | /** |
| 1072 | 1112 | * Throw an exception that the concrete is not instantiable. |
| 1073 | 1113 | * |
| 1074 | 1114 | * @param string $concrete |
| 1075 | - * @return void | |
| 1115 | + * @return never | |
| 1076 | 1116 | * |
| 1077 | 1117 | * @throws \FluentBoards\Framework\Container\Contracts\BindingResolutionException |
| 1078 | 1118 | */ |
| 1079 | 1119 | protected function notInstantiable($concrete) |
| @@ -1110,9 +1150,9 @@ | ||
| 1110 | 1150 | * @param \Closure|string $abstract |
| 1111 | 1151 | * @param \Closure|null $callback |
| 1112 | 1152 | * @return void |
| 1113 | 1153 | */ |
| 1114 | - public function beforeResolving($abstract, Closure $callback = null) | |
| 1154 | + public function beforeResolving($abstract, ?Closure $callback = null) | |
| 1115 | 1155 | { |
| 1116 | 1156 | if (is_string($abstract)) { |
| 1117 | 1157 | $abstract = $this->getAlias($abstract); |
| 1118 | 1158 | } |
| @@ -1130,9 +1170,9 @@ | ||
| 1130 | 1170 | * @param \Closure|string $abstract |
| 1131 | 1171 | * @param \Closure|null $callback |
| 1132 | 1172 | * @return void |
| 1133 | 1173 | */ |
| 1134 | - public function resolving($abstract, Closure $callback = null) | |
| 1174 | + public function resolving($abstract, ?Closure $callback = null) | |
| 1135 | 1175 | { |
| 1136 | 1176 | if (is_string($abstract)) { |
| 1137 | 1177 | $abstract = $this->getAlias($abstract); |
| 1138 | 1178 | } |
| @@ -1150,9 +1190,9 @@ | ||
| 1150 | 1190 | * @param \Closure|string $abstract |
| 1151 | 1191 | * @param \Closure|null $callback |
| 1152 | 1192 | * @return void |
| 1153 | 1193 | */ |
| 1154 | - public function afterResolving($abstract, Closure $callback = null) | |
| 1194 | + public function afterResolving($abstract, ?Closure $callback = null) | |
| 1155 | 1195 | { |
| 1156 | 1196 | if (is_string($abstract)) { |
| 1157 | 1197 | $abstract = $this->getAlias($abstract); |
| 1158 | 1198 | } |
| @@ -1389,9 +1429,9 @@ | ||
| 1389 | 1429 | * |
| 1390 | 1430 | * @param \FluentBoards\Framework\Container\Contracts\Container|null $container |
| 1391 | 1431 | * @return \FluentBoards\Framework\Container\Contracts\Container|static |
| 1392 | 1432 | */ |
| 1393 | - public static function setInstance(ContainerContract $container = null) | |
| 1433 | + public static function setInstance(?ContainerContract $container = null) | |
| 1394 | 1434 | { |
| 1395 | 1435 | return static::$instance = $container; |
| 1396 | 1436 | } |
| 1397 | 1437 | |
| @@ -1442,9 +1482,13 @@ | ||
| 1442 | 1482 | */ |
| 1443 | 1483 | #[\ReturnTypeWillChange] |
| 1444 | 1484 | public function offsetUnset($key) |
| 1445 | 1485 | { |
| 1446 | - unset($this->bindings[$key], $this->instances[$key], $this->resolved[$key]); | |
| 1486 | + unset( | |
| 1487 | + $this->bindings[$key], | |
| 1488 | + $this->instances[$key], | |
| 1489 | + $this->resolved[$key] | |
| 1490 | + ); | |
| 1447 | 1491 | } |
| 1448 | 1492 | |
| 1449 | 1493 | /** |
| 1450 | 1494 | * Dynamically access container services. |