dependency injection in laravel

27
Dependency Inversion Dependency Injection Contract SOLID Service Provider Service Container IoC DI

Upload: hao-wen-zhang

Post on 15-Jul-2015

583 views

Category:

Software


4 download

TRANSCRIPT

Dependency Inversion

Dependency Injection

Contract

SOLID

Service ProviderService Container

IoC

DI

Dependency InversionSOLID

High-level modules should not depend on low-level modules. Both should depend on abstractions.

http://en.wikipedia.org/wiki/Dependency_inversion_principle

⾼高階模組不應該依賴低階模組。 兩者都應該要依賴於抽象

What the …

class UserModify { public function __constructor() {

$this->storage = new MysqlStorage(); }

public function modify($data) { $result = $this->storage->save($data); return $result;

} }

⾼高階直接依賴低階

class UserModify { public function __constructor(DataStorageInterface $storage) {

$this->storage = $storage; }

public function modify($data) { $result = $this->storage->save($data); return $result;

} }

class MysqlStorage implements DataStorageInterface { public function save($data){ // …. }

}

interface DataStorageInterface { public function save(array $data);

}

Abstraction

Low Level Module

Hight Level Module

Why

#隱藏低階模組的細節

#容易抽換實作

#程式碼變多

#追蹤⽐比較困難

#讓測試變容易 #⽐比較不直覺

隱藏低階模組的細節

class UserModify { public function __constructor() { $dbConfig = [….];

$this->storage = new MysqlStorage($dbConfig); }

}

容易抽換實作

class UserModify { public function __constructor(DataStorageInterface $storage) {

$this->storage = $storage; }

}

class SqliteStorage implements DataStorageInterface { public function save($data){ // …. }

}

SqliteStorage Instance

讓測試變容易

class DummyStorage implements DataStorageInterface { public function save() { return ‘Success’; }

}

class UserModify { public function modify($data) {

return $this->storage->save($data); }

}

class UserModifyTest { public function it_return_new_instance_after_modify($data) {

$instance = new UserModify(new DummyStorage); $result = $instance->modify();

assert($result, ‘Success’); }

}

How

Inverse of Control

http://zh.wikipedia.org/wiki/%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC

Dependency Injection

http://en.wikipedia.org/wiki/Dependency_injection

Dependency injection is a software design pattern that implements inversion of control for software libraries, where the caller delegates to an external framework the control flow of discovering and importing a service or software module.

ServiceProvider

Container

http://laravel.tw/docs/5.0/providers

Service Provider

.

├── AppServiceProvider.php

├── BusServiceProvider.php

├── ConfigServiceProvider.php

├── EventServiceProvider.php

├── FilterServiceProvider.php

├── RepoServiceProvider.php

└── RouteServiceProvider.php

app/Providers

<?php namespace Backend\Providers; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function register() {

$this->app->bind( ‘Jaster/Interfaces/FooInterface’, ‘Jaster/Implements/FooImplementClass’ ); }}

app/Providers/AppServiceProvider.php

'providers' => [ /* * Laravel Framework Service Providers... */ 'Illuminate\Foundation\Providers\ArtisanServiceProvider', 'Illuminate\Auth\AuthServiceProvider', 'Illuminate\Bus\BusServiceProvider', 'Illuminate\Cache\CacheServiceProvider', 'Illuminate\Foundation\Providers\ConsoleSupportServiceProvider', 'Illuminate\Routing\ControllerServiceProvider',

// ….],

config/app.php

Service Container

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

http://laravel.com/docs/5.0/container

Trace initialize of service container ( Illuminate\Foundation\Application )

Illuminate\Foundation\Application::__construct

Illuminate\Foundation\Application::registerBaseBindings

Illuminate\Foundation\Application::registerBaseServiceProviders

Illuminate\Foundation\Application::registerCoreContainerAliases

Trace register of Illuminate\Contracts\Http\Kernel

bootstrap/app.php $app->singleton(‘Illuminate\Contracts\Http\Kernel', 'App\Http\Kernel');

Illuminate\Foundation\Application::singleton

Illuminate\Foundation\Application::bind

Trace how to use Illuminate\Contracts\Http\Kernel

$kernel = $app->make('Illuminate\Contracts\Http\Kernel');public/index.php

Illuminate\Foundation\Application::make

Illuminate\Container\Container::make

Illuminate\Container\Container::build

Trace Facade autoloader

Illuminate\Foundation\Http\Kernel::bootstrap

Illuminate\Foundation\Application::bootstrapWith

Illuminate\Foundation\Bootstrap\RegisterFacades

Illuminate\Foundation\AliasLoader::register

Illuminate\Foundation\AliasLoader::prependToLoaderStack

PHP UK Conference 2014 - Stephan Hochdorfer - The 7 Deadly Sins of Dependency Injection

https://www.youtube.com/watch?v=hMix8gfDy54

Thank you