Look laravel source learning Dependency Injection

Foreword

Original intention

Look at the recent design mode of dependency injection, hoping to design patterns of magic, to achieve a purpose, and then in the course of this learning process, can gain a bonus.
The purpose is to design their own systems enables simpler and more readily understood, or such structures and code simpler system design, and an attempt to achieve concurrent bonus conceptual design on mode.
This article is to put their learning outcomes during this time to make a record and summary, but not to expect too much, because at present the conclusions did not achieve my purpose, bonus being relatively slim hope.

Ready knowledge of the network structure of cognitive

We need to know in advance what the relationship Dependency Inversion Principle, Inversion of Control and Dependency Injection.
Inversion of Control is a design that follows the Dependency Inversion Principle, Inversion of Control is achieved mainly general manner or means of dependency injection.
Dependency Inversion Principle This article does not explain, we can look at.

A chatter and chatter dependency injection IoC

Dependency Injection is what is it

Here are a few concepts first need to describe it, first of all we need to have a 主体, this 主体is 注入a 依赖, 主体by using these 依赖to do some behavior or implement some operations.
主体Refers to the number of entities on the system design, such as a gig class to implement create, modify, review business logic, then this class is a gig 主体, there is another example of such a business logic: violation of Record It contains multiple violations indicators. This time the violation Indicator, is a 主体.
依赖It refers to the 主体need to rely on one another 主体to achieve a certain function, such as in the example just the kind of gig to rely on illegal Indicator to achieve the creation of gigs logic, logic created in the need to record what the article gig violation indicators, and the need for indicators of illegal business check here gig like this 主体need to rely on indicators like this illegal 主体achieve some action, then the violation indicator this 主体is a gig like this 主体is 依赖.
As 注入, referring to 主体how to obtain 依赖, a common way to have passed through the constructor argument to class methods and parameters, simply, is this:

依赖 = new 主体B();
对象 = new 主体A(依赖);
对象.实现功能();
IoC container
What is the IoC

What is Inversion Of Control (IoC) it, here we must first understand how the control is transferred, control or subject to other restrictions in the process is entirely within the body is to control forward, in fact, is what we usually write code posture , for example it is:

class A
{
  public function 实现功能() { 对象B = new B(); 对象B.检查一下商品数量(); 对象C = new C(); 对象C.检查一下优惠(); return "牛逼!"; } } 对象A = new A(); 对象A.实现功能(); 

Inversion of Control refers to the control of other subjects is not within a body does not need to personally create the object, but the object is obtained by injecting a way, yes, dependency injection above example is the inversion of control, generally use dependency injection inversion of control is achieved, for example, that:

class A
{
  B 对象B;
  C 对象C;
  public __construct(B 对象B, C 对象C) { this.对象B = 对象B; this.对象C = 对象C; } public function 实现功能() { this.对象B.检查一下商品数量(); this.对象C.检查一下优惠(); return "牛逼!"; } } // 同时也是依赖注入的例子 对象B = new B(); 对象C = new C(); 对象A = new A(对象B, 对象C); 对象A.实现功能(); 
Why should IoC container, to achieve what effect

Ok! Introduction to the concept of IoC, and that is what IoC container does, in fact, is to create objects of work receive a "container" so that the code becomes more simple and concise.
On the basis of the example above, the effect to be achieved is simply:

// 类A代码没有变动

容器 = new 容器();
容器.绑定(B);
容器.绑定(C);
容器.绑定(A);

对象A = 容器.制造(A);
对象A.实现功能();

laravel IoC container Detailed

Use IoC container to inject dependencies, we can more easily manage and use dependency, where it is necessary to look at the concrete realization of IoC container, we can look for well-known industry achieve: IoC container laravel, the probe to explore where exactly.
The basic operation of IoC container has two, binding and production of objects, we can based on the basic operation of the two containers to enter the interior IoC container.

Basic operation IoC container

Basic use

Use laravel IoC container and use of the container is substantially consistent with the above-described examples, a subject is to bind the body here refers to a class or an object; Another corresponding object is created, the object is to use complete a variety of business logic or functional.

Binding

laravel container will maintain multiple binding relationship, when used in the production of the object to resolve the corresponding class in order to create objects of this class, the binding relationship about the following, interested readers can access container class property, here a brief introduction to the relationship between the binding relationship and calls for reference:

  • $ Resolved: Record whether a binding relationship has been resolved, that is, whether the object is created too;
  • $ Bindings: Interface A recording is achieved class a, is the array [A => a];
  • $ MethodBindings: Record bind with a certain method, specific principles to be get to the bottom;
  • $ Instances: record an object, this object is returned directly to create objects;
  • $ Aliases: a class record their aliases, such as is [ "class A" => "cache (alias class A)"]
  • $ AbstractAliases: alias which has a record type, for example a [ "cache" => [ "redis class", "class memcache"]]
  • $ Extenders: with some kind of binding to the closure function up, these closures may be obtained by the functions getExtenders method, to be specific principle go into;
  • $ Tags: Tag marked certain class, the data structure is a [ "cache_tag" => [ "redis class", "class memcache"]] can be batch operations, the specific use to be get to the bottom;
  • $ BuildStack: Log all objects have been created;
  • $ With: records all parameters have been created objects;
  • $ Contextual: add a context-bound, specific principles to be get to the bottom;
  • $ ReboundCallbacks: to be get to the bottom
  • $ GlobalResolvingCallbacks: to be get to the bottom
  • $ GlobalAfterResolvingCallbacks: to be get to the bottom
  • $ ResolvingCallbacks; to be get to the bottom
  • $ AfterResolvingCallbacks: to be get to the bottom

Part of the call relationship:

resolved[]:
1. Container.resolved
2. Container.resolve
3. Container.flush
4. Container.offsetUnset

bindings[]:
1. Container.bind
2. Container.isShare
3. Container.getConcrete
4. Container.flush
5. Container.offsetUnset
6. Container.Bound
7. Container.getBindings

instances[]:
1. Application.make //只用于判断,然后延迟注册provider
2. Container.bound
3. Container.resolved
4. Container.isShared
5. Container.extend
6. Container.instance
7. Container.resolve
8. Container.dropStaleInstances
9. Container.forgetInstance
10. Container.forgetInstances
11. Container.flush
12. Container.offsetUnset

aliases[]:
1. Container.isAlias
2. Container.instance
3. Container.removeAbstractAlias
4. Container.alias
5. Container.getAlias
6. Container.dropStaleInstances
7. Container.flush

abstractAliases[]: 记录某类有哪些alias
methodBindings[]: 方法绑定
extenders[]: 扩展关系
tags[]: 给abstracts打tag

......

The following detailed description is bindings, intances and aliases.

  • bindings
    This may be referred to bind class relationships, i.e. when the container resolved manner to give the object created, the closure may be a function of the class name or create an object, you can create a corresponding object based on the class or function. bindings can be classified into the following categories:

    • Bind itself, with code shows more clear:
      $this->app->bind('App\Services\RedisEventPusher', null);
      
    • Binding closure
      $this->app->bind('HelpSpot\API', function ($app) { return new HelpSpot\API(); });//闭包直接提供实现方式 
    • Binding Interface
      $this->app->bind(
        'App\Contracts\EventPusher',  // Interface
        'App\Services\RedisEventPusher'   // 实现功能的具体类 ); 
  • instances
    objects intances binding refers to binding has been created, does not need help to create a container object is simple:

    $api = new HelpSpot\API(new HttpClient);
    $this->app->instance('HelpSpot\Api', $api);
    
  • aliases
    alias binding, in short, to maintain a KV Dui, K is an alias, V is the object class name (or vice versa (aliases)), this more direct look at the source code at a glance:

    foreach ([
          'db'                   => [\Illuminate\Database\DatabaseManager::class],
          'db.connection'        => [\Illuminate\Database\Connection::class, \Illuminate\Database\ConnectionInterface::class],
          'events'               => [\Illuminate\Events\Dispatcher::class, \Illuminate\Contracts\Events\Dispatcher::class],
          ......
      ] as $key => $aliases) { foreach ($aliases as $alias) { $this->alias($key, $alias); } } 

    That $ this-> alias to achieve it? The method is very simple to achieve alias, the alias is not resolved in the course of the following description IoC Lane, mainly maintenance and abstractAliases two aliases alias relationship, php are two arrays, a source of you glance> <:

    public function alias($abstract, $alias) { ... $this->aliases[$alias] = $abstract; $this->abstractAliases[$abstract][] = $alias; } 
Analysis and production of objects

It is to use make to create objects.

public function make($abstract, array $parameters = []) { // resolve 方法解析对象 return $this->resolve($abstract, $parameters); } 

Execution flow IoC container

The above describes laravel container if used, that is, how to use the container corresponding method binding classes / objects and create objects we need.
Let's take a look bind action and make the action of specific implementation process.

bind action process
public function bind($abstract, $concrete = null, $shared = false) { $this->dropStaleInstances($abstract); if (is_null($concrete)) { $concrete = $abstract; } if (! $concrete instanceof Closure) { $concrete = $this->getClosure($abstract, $concrete); } $this->bindings[$abstract] = compact('concrete', 'shared'); if ($this->resolved($abstract)) { $this->rebound($abstract); } } 
make operation process (Resolve)
instance the course of action

Guess you like

Origin www.cnblogs.com/varXinYuan/p/11546415.html