laravel Dependency Injection Analysis

laravel container comprises injection control and dependency inversion, it is to use, a good object first bind, may be used when needed to make direct taking like.

Usually we call as follows.

config = Container- $ $> the make ( 'config');
$ = new Connection Connection ($ this-> config);

better understood, this advantage is not a new instance of a direct process lacks traditional values change, further many can share this instance.

But this dependence have anything to do with the injection, the real dependency injection method is not required to pass any parameters, only you need to specify the method parameter types, code lookup relationship rely on automatic injection.

This feature can be reflected in laravel the Controller, Job, etc., as follows:

class TestController extends Controller
{
public function anyConsole(Request $request, Auth $input)
{
//todo
}
}


We look at how he is automatic dependency injection:

, Through layers of pipes called by the Kernel Kernel call index.php, then Router, through layers of middleware pipeline calls. The final positioning

Illuminate / Routing / Route.php 124th row.

public function run(Request $request)
{
$this->container = $this->container ?: new Container;
try {
if (! is_string($this->action['uses'])) {
return $this->runCallable($request);
}

if ($this->customDispatcherIsBound()) {
return $this->runWithCustomDispatcher($request);
}

return $this->runController($request);
} catch (HttpResponseException $e) {
return $e->getResponse();
}
}


Analyzing $ this-> action [ 'uses'] (such as line format: \ App \ Http \ Controller \ Datacenter \ RealTimeController @ anyConsole) if the string, $ this-> customDispatcherIsBound determines whether a user-defined binding route. Then jump to $ this-> runController ($ request).

protected function runController(Request $request)
{
list($class, $method) = explode('@', $this->action['uses']);

$parameters = $this->resolveClassMethodDependencies(
$this->parametersWithoutNulls(), $class, $method
);

if (! method_exists($instance = $this->container->make($class), $method)) {
throw new NotFoundHttpException;
}

call_user_func_array return ([$ instance, Method, $], $ the Parameters);
}

$ this-> resolveClassMethodDependencies this method to see the name to know is the way we're looking for. $ this-> parametersWithoutNulls () is a filter null character, $ class, $ method such as lines, respectively: \ App \ Http \ Controller \ Datacenter \ RealTimeController and anyConsole.

protected function resolveClassMethodDependencies(array $parameters, $instance, $method)
{
if (! method_exists($instance, $method)) {
return $parameters;
}

$ this- return> resolveMethodDependencies (
$ Parameters, new new ReflectionMethod ($ instance, $ Method)
);
}

new new ReflectionMethod ($ instance, $ Method) reflected by the object is to get the class methods, see documentation: http: //www.php .net / manual / zh / class.reflectionmethod.php

The following jump to Illuminate / Routing / RouteDependencyResolverTrait.php line 54.

public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector)
{
$originalParameters = $parameters;

foreach ($reflector->getParameters() as $key => $parameter) {
$instance = $this->transformDependency(
$parameter, $parameters, $originalParameters
);

if (! is_null($instance)) {
$this->spliceIntoParameters($parameters, $key, $instance);
}
}

Parameters $ return;
}

to obtain an array of parameters class class method through reflection, and then transmitted to the traverse $ this-> transformDependency method. If an instance is invoked get less than $ this-> spliceIntoParameters clear this parameter.

transformDependency function protected (ReflectionParameter Parameter $, $ Parameters, originalParameters $)
{
$ = $ parameter-class> getClass ();
IF (! $ class && $ this-> alreadyInParameters ($ class-> name, $ Parameters)) {
return this- $> Container-> make ($ class-> name);
}
}

finally see the shadow of the container, that's right eventually taken out by the object or make the method container. Well constructed on this parameter, then end up being call_user_func_array runController callback method.

Summary:
1. The principle is dependent injection method is the use of a reflective type, for obtaining a parameter type, then a good example of the use of the container structure. Then use the callback function calls from.
2. Fill object constructor not have parameters. Otherwise it will error. 1 argument Missing
3. However, dependency injection so good, but it must be played by the Router class transfer, or direct way with a new injection can not be achieved. So this is why only Controller, Job class in order to use this feature up.

Guess you like

Origin www.cnblogs.com/starluke/p/11791478.html