Laravel constructor automatically depends on the injection method, laravel Constructor

Source: Internet
Author: User
Tags reflector

Laravel constructor automatically depends on the injection method, laravel Constructor

This example describes how Laravel implements automatic constructor dependency injection. We will share this with you for your reference. The details are as follows:

In Laravel constructor, automatic dependency injection can be implemented without instantiating the required class before instantiation, as shown in the Code:

<?phpnamespace Lio\Http\Controllers\Forum;use Lio\Forum\Replies\ReplyRepository;use Lio\Forum\Threads\ThreadCreator;use Lio\Forum\Threads\ThreadCreatorListener;use Lio\Forum\Threads\ThreadDeleterListener;use Lio\Forum\Threads\ThreadForm;use Lio\Forum\Threads\ThreadRepository;use Lio\Forum\Threads\ThreadUpdaterListener;use Lio\Http\Controllers\Controller;use Lio\Tags\TagRepository;class ForumThreadsController extends Controller implements ThreadCreatorListener, ThreadUpdaterListener, ThreadDeleterListener{ protected $threads; protected $tags; protected $currentSection; protected $threadCreator; public function __construct(  ThreadRepository $threads,  ReplyRepository $replies,  TagRepository $tags,  ThreadCreator $threadCreator ) {  $this->threads = $threads;  $this->tags = $tags;  $this->threadCreator = $threadCreator;  $this->replies = $replies; }}

Note that there are several type constraints in the constructor. In fact, there is no place to instantiate this Controller and pass these types of parameters into it. Laravel will automatically detect the type constraint parameters in the constructor of the class, and automatically identifies whether to initialize and pass in.

The build method in the source code vendor/illuminate/container/Container. php is as follows:

$constructor = $reflector->getConstructor();dump($constructor);

The constructor of the class will be parsed here, and printed here:

It will find out the parameters of the constructor, and then look at the operations performed by the complete build method:

public function build($concrete, array $parameters = []){ // If the concrete type is actually a Closure, we will just execute it and // hand back the results of the functions, which allows functions to be // used as resolvers for more fine-tuned resolution of these objects. if ($concrete instanceof Closure) {  return $concrete($this, $parameters); } $reflector = new ReflectionClass($concrete); // If the type is not instantiable, the developer is attempting to resolve // an abstract type such as an Interface of Abstract Class and there is // no binding registered for the abstractions so we need to bail out. if (! $reflector->isInstantiable()) {  $message = "Target [$concrete] is not instantiable.";  throw new BindingResolutionContractException($message); } $this->buildStack[] = $concrete; $constructor = $reflector->getConstructor(); // If there are no constructors, that means there are no dependencies then // we can just resolve the instances of the objects right away, without // resolving any other types or dependencies out of these containers. if (is_null($constructor)) {  array_pop($this->buildStack);  return new $concrete; } $dependencies = $constructor->getParameters(); // Once we have all the constructor's parameters we can create each of the // dependency instances and then use the reflection instances to make a // new instance of this class, injecting the created dependencies in. $parameters = $this->keyParametersByArgument(  $dependencies, $parameters ); $instances = $this->getDependencies(  $dependencies, $parameters ); array_pop($this->buildStack); return $reflector->newInstanceArgs($instances);}

How to obtain an instance from a container:

protected function resolveClass(ReflectionParameter $parameter){ try {  return $this->make($parameter->getClass()->name); } // If we can not resolve the class instance, we will check to see if the value // is optional, and if it is we will return the optional parameter value as // the value of the dependency, similarly to how we do this with scalars. catch (BindingResolutionContractException $e) {  if ($parameter->isOptional()) {   return $parameter->getDefaultValue();  }  throw $e; }}

The bottom layer of the framework uses Reflection to save a lot of details for development and implement automatic dependency injection. I will not continue to study it here.

I wrote a class test to simulate this process:

<?phpclass kulou{ //}class junjun{ //}class tanteng{ private $kulou; private $junjun; public function __construct(kulou $kulou,junjun $junjun) {  $this->kulou = $kulou;  $this->junjun = $junjun; }}//$tanteng = new tanteng(new kulou(),new junjun());$reflector = new ReflectionClass('tanteng');$constructor = $reflector->getConstructor();$dependencies = $constructor->getParameters();print_r($dependencies);exit;

The principle is to use the ReflectionClass class to parse the constructor class and retrieve the constructor parameters, so as to determine the dependency, retrieve the constructor from the container, and inject the constructor automatically.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.