IoC Container
<a name="introduction"></a> ## Introduction >หมายเหตุ :: ถ้าใครยังไม่ค่อยเข้าใจว่าสองตัวนี้มันคืออะไรลองไปอ่านที่ผมสรุปไว้ที่นี้ก่อนครับ
IOC คือคลาสที่ใช้ในการจัดการ library ภายนอกที่เรานำเข้ามาใช้ หรือที่ดึงเข้ามาใช้โดย composer ต่อไปนี้จะเรียกย่อๆว่า IOC นะครับ
IOC จะช่วยในการเรียกใช้งานคลาสต่าง การทำความเข้าใจ IOC ถือว่าเป็นหัวใจ เลยในการปูทางสู่การทำเว็บขนาดใหญ่สำหรับ
laravel นะครับ เพราะหลักการนี้จะเกี่ยวโยงไปถึงเรื่อง Service Provider กับ Facade
<a name="basic-usage"></a> ## การใช้งานเบื้องต้น
การใช้งาน IOC ในการผูก object
1 App::bind('foo', function($app)
2 {
3 return new FooBar; //
4 });
ง่ายคือต่อไปนี้พารามิเตอร์ชื่อ foo จะใช้เป็นตัวแทนของ class FooBar ที่ถูกสร้างเป็นวัตถุแแล้ว
การเรียกใช้งาน
1 $value = App::make('foo');
เมื่อเราเรียกใช้งาน App::make เมทอด ฟังก์ชันข้างบนก็จะถูกเรียกใช้งาน ตัวแปร value
ก็จะรับคุณสมบัติต่างๆ ของคลาส FooBar เข้ามา
บางครั้งเราไม่ต้องการสร้าง instane ทุกครั้งที่รีเฟรช laravel มีฟังก์ชัน singleton มาให้ใช้ในการนี้เลยครับ
<br /><br /><br /><br /><br /><br />
ตัวอย่างการใช้งาน
1 App::singleton('foo', function()
2 {
3 return new FooBar;
4 });
ถ้าไม่ต้องการจัดเพิ่มเข้าไปทั้งคลาสจะยัดเข้าไปเป็นออปเจ็คก็ใช้ฟังก์ชัน instance ได้เลยครับ
ตัวอย่างการผูกออปเจคเข้าไป
1 $foo = new Foo;
2
3 App::instance('foo', $foo);
<br /><br /><br /> <a name="automatic-resolution"></a> ## Automatic Resolution
ตัวอย่างการผูกคลาสอย่างรวดเร็วขึ้นโดยไม่ต้องใช้ App::bind แล้วแต่ขอให้ชื่อตรงกันก็พอ
ตัวอย่าง
1 class FooBar {
2
3 public function __construct(Google $baz)
4 {
5 $this->baz = $baz;
6 }
7
8 }
9
10 $fooBar = App::make('FooBar');
ในตัวอย่างนี้ ตัวแปร $foofBar จะเก็บค่าคลาส Google ที่ถูกแทรกเข้ามา
laravel จะทำการเรียกใช้ reflection class ของ php เพื่อทำการตรวจสอบค่าต่างๆ ในคลาสนั้นให้เองครับ
บางกรณีคลาสที่เราจะใช้งานดันไปดึงคลาสที่เป็น interface เข้ามาใช้ด้วย เพื่อการนั้นเราต้องใช้ App::bind เมทอด ในการผูก ดังตัวอย่าง
ตัวอย่างการผูก class ที่เป็นเรียกใช้งาน interface
1 App::bind('UserRepositoryInterface', 'DbUserRepository');
คลาสที่เราเรียกใช้งาน
1 class UserController extends BaseController {
2
3 public function __construct(UserRepositoryInterface $users)
4 {
5 $this->users = $users;
6 }
7
8 }
ตอนนี้ UserRepositoryInterface จะถูกเรียกใช้งานแล้ว
<a name="practical-usage"></a>
## การประยุกต์ใช้งาน
เพื่อความยืดหยุ่นในการทดสอบและใช้งาน Laravel เตรียมการให้เราใช้งาน IOC ไในหลายกรณีเลยครับ
ตัวอย่างการเรียกใช้งาน Class OrderRepository
1 class OrderController extends BaseController {
2
3 public function __construct(OrderRepository $orders)
4 {
5 $this->orders = $orders;
6 }
7
8 public function getIndex()
9 {
10 $all = $this->orders->all();
11
12 return View::make('orders', compact('all'));
13 }
14
15 }
ในตัวอย่างคลาส OrderRepository แทรกเข้าไปโดยอัติโนมัติเมื่อ คลาส OrderController ทำงาน เมื่อมีการทำ unit testing คลาส OrderRepository ก็จะถูกเพิ่มเข้ามาเหมือนกัน
Filters, composers และ event handlers อยู่นอกเหนือการทำงานของ IoC container เมื่อเราจะใช้ต้องทำตามตัวอย่างครับ
การใช้งาน View::composer,Route::filter และ Event::listen กับ IOC
1 Route::filter('foo', 'FooFilter');
2
3 View::composer('foo', 'FooComposer');
4
5 Event::listen('foo', 'FooHandler');
<a name="service-providers"></a> ## Service Providers
Service providers เป็นการจับคลาส IOC ที่ทำงานคล้ายกันเข้ามาไว้ในที่เดียวกัน.
แล้วเรียกใช้งาน ด้วย facade
โดยหลักเเล้วทุกคลาสหลักของ laravel ใช้การทำ service provider ในการจัดการเราสามารถเข้าไปดูได้ตรงที่ตัวแปรอาเรย์ providers ตรงที่app/config/app.php
จะสร้าง Service Provider ขึ้นมาใช้กับคลาสของเราเริ่มแรกต้องดึงคลาส Illuminate\Support\ServiceProvider และประกาศเมทอด register
ตัวอย่างการสร้าง Service Provider
1 use Illuminate\Support\ServiceProvider;
2
3 class FooServiceProvider extends ServiceProvider {
4
5 public function register()
6 {
7 $this->app->bind('foo', function()
8 {
9 return new Foo;
10 });
11 }
12
13 }
ในเมทอด register คลาส IOC จะเป็นตัวแปร $this->app ถ้าเราทำเสร็จแล้วก็ต้องเอาเส้นทางที่อยู่ของคลาส Provider ของเราไปเพิ่มในอาเรย์ providers ใน app.php ด้วย
การเรียกใช้งาน Service Provider ด้วยเมทอด App::register
<br /><br /><br /><br />
ตัวอย่าง
1 App::register('FooServiceProvider');
<a name="container-events"></a> ## Container Events
ใน IOC ก็มี event อยู่ชื่อเมทอดว่า resolving
การใช้งาน resoliving เพื่อรอดูว่ามี IOC ตัวไหนทำงานบ้าง
1 App::resolving(function($object)
2 {
3 //
4 });