Laravel dependency injection and control inversion

Source: Internet
Author: User
Tags reflector
Laravel dependency injection and control reversal

Dependency InjectionWhen I first came into contact with this word, I was confused by some of the two monks. so today we will explore the dependency injection in Laravel ), to understand it.Control reversalThe first impression is an esoteric term... Does it look like reverse control? Don't you understand? Then straighten it out!

What is dependency?

I cannot survive without you, so you are my dependency. To put it bluntly, it is:

Not my own, but what I need is what I depend on. All services that require external provision require dependency injection.

We use code to describe:

Class Boy {protected $ girl; public function _ construct (Girl $ girl) {$ this-> girl = $ girl ;}} class Girl {...} $ boy = new Boy (); // Error; Boy must have girlfriend! // So he must have a girlfriend. $ girl = new Girl (); $ boy = new Boy ($ girl); // Right! So Happy!

From the above code, we can see that the Boy's strong dependence on Girl must inject the Girl instance during the construction.

So why is dependency injection the concept of dependency injection solved?

The above code is corrected by the code we wrote at the beginning:

class Boy {  protected $girl;  public function __construct() {    $this->girl = new Girl();  }}

What is the difference between this method and the previous one?

We will find that the Boy's girlfriend is hard coded into the Boy's body... Every time a Boy is born again, he wants to change the type of his girlfriend, he has to hide himself... (⊙ O ⊙ )...

One day, Boy really liked a LoliGirl and wanted her to be her girlfriend... What should I do? Reborn yourself... Open yourself... Throwing Girl away... Put LoliGirl in...

class LoliGirl {}class Boy {  protected $girl;   public function __construct() {      //  $this->girl = new Girl();  // sorry...      $this->girl = new LoliGirl();  }}

One day, Boy fell in love with Yu Jie... (⊙ o ⊙ )... Boy is so annoying...

Doesn't it feel bad? Every time I meet someone who really treats each other, I want to torture myself like this...

Boy said, I want to become more powerful. I don't want to be changed!

Okay, let's make Boy more powerful:

interface Girl {  // Boy need knows that I have some abilities.}class LoliGril implement Girl {  // I will implement Girl's abilities.}class Vixen implement Girl {  // Vixen definitely is a girl, do not doubt it.}class Boy {  protected $girl;  public function __construct(Girl $girl) {    $this->girl = $girl;  }}$loliGirl = new LoliGirl();$vixen = new Vixen();$boy = new Boy($loliGirl);$boy = new Boy($vixen);

Boy is so happy that he can try different life without having to reveal himself... So Happy!

Summary

Because most applications use two or more classes to implement business logic through mutual cooperation, so that each object needs to obtain the objects it cooperates with (that is, the objects it depends on). If this acquisition process depends on its own implementation, the code will be highly coupled and difficult to maintain and debug.

Therefore, with the concept of dependency injection, dependency injection solves the following problems:

  • Decoupling between dependencies
  • Unit testing for Mock convenience

=. = The previous dependency injection actually requires us to manually inject dependencies. as a programmer, how can we tolerate this inefficient injection method? well, let's take a look at it first.IOCConcept.

Inversion Of Control, IOC)

Control reversalIt is a design principle in object-oriented programming and can be used to reduce the coupling degree between computer code. The most common method isDependency Injection(Dependency Injection, DI), and Dependency Lookup ). When an object is created, the external entity of all objects in a control system transmits the reference of the object to it. It can also be said that the dependency is injected into the object.

That is to say, we need a control system. In this control system, we store some object entities or object descriptions. When an object is created, the reference of the object on which the object depends is passed. In Laravel, Service Container is an efficient control system, which is the core of laravel. Next, let's take a look at how laravel implements automatic dependency injection.

Laravel dependency injection

Now we can see the example given in the document, which is not difficult to understand:

 mailer = $mailer;    }    /**     * Purchase a podcast.     *     * @return void     */    public function handle()    {        //    }}

In this example, the PurchasePodcast job needs to send e-mails when a podcast is purchased. So, we willInjectA service that is able to send e-mails. since the service is injected, we are able to easily swap it out with another implementation. we are also able to easily "mock", or create a dummy implementation of the mailer when testing our application.

Speaking of laravel dependency injection, we have to understand laravel's Service Container.

Service Container)

The Laravel service container is a powerful tool for managing class dependencies and padding dependency injection. dependency injection is a fancy phrase that essential means this: class dependencies are "injected" into the class via the constructor or, in some cases, "setter" methods.

From the introduction, it is not difficult to see that the service container is the control reversal container, which is the scheduling system mentioned above. The method for implementing dependency injection can be in the constructor or setter method.

If we carefully study the Service Container, we will find that laravel's Service Container only stores the object description, and does not need to know how to construct an object, because it automatically parses an object according to php's reflection service.

Reflection

In computer science,ReflectionA computer can access, detect, and modify its own status or behavior at Run time. In a metaphor, a program can "observe" and modify its own behavior.

The language supporting reflection provides some runtime features that are difficult to implement in low-level languages. These features include

  • Discover and modify the source code structure (such as code blocks, classes, methods, protocols, etc.) as a first-class object ).
  • Converts a class or function to a class or function call or reference.
  • Calculate a string like a source code statement at runtime.
  • Create a new language bytecode interpreter to give the programming structure a new meaning or purpose.

PHP reflection can be viewed in the official documentation:Reflection API

Example
$reflector = new ReflectionClass('App\User');if ($reflector->isInstantiable()) {  $user = $refector->newInstance(); //in other case you can send any arguments}

In the build method of laravel service containers, dependencies need to be resolved through reflection services. for example, what dependency parameters need to be passed in the construct function? The following method is required:

   $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();

Now we have some idea about how laravel can implement automatic dependency injection? To sort out the questions:

  • How to implement automatic dependency injection? (Control inversion, using reflection)
  • What are the requirements for dependency injection? (Sort out the dependency [construct | setter] and parse the dependency to pass the reference)
  • How to resolve dependencies?

You may ask why to resolve the dependency? Reflection must be used for parsing dependencies. reflection. do you know that the class name can be directly parsed?

Actually... This is not the case... (@ Brief @)

In many cases, to improve code scalability and maintainability, we rely on interfaces or abstract classes when writing classes, rather than a specific implementation class. Do you understand? If only the interface or abstract class is parsed during Dependency Parsing and reflection is used, this dependency is definitely incorrect.

In this case, we need to inject the ing relationships of related dependencies in the scheduling system, and then correctly parse the relationships as needed. For example, Hello, I need A. don't give it to B.

$container->bind('a', function () {  return new B();  // just this for you});$a = $container->make('a');
Summary
  • Dependency injection is an implementation of control inversion, implementing code decoupling to facilitate unit testing. Because it does not need to understand the classes it depends on, it only needs to know that the classes it depends on implement the methods it needs. You need me, but you don't know me )/~~
  • Control inversion provides a control system for automatic injection of Dependency Parsing. generally, it works with containers to provide reference for dependent object instances.

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.