PHP

IoC Container, và vận dụng Reflection trong PHP

Ví dụ:
Gọi class "A" là class cần sử dụng class "B", và class "B" cần sử dụng class "C".

Trong trường hợp không sử dụng IoC Container

Class "A" sẽ có một constructor nhận class "B" làm tham số và class "B" sẽ có một constructor nhận class "C" làm tham số. Nếu muốn tạo một đối tượng của class "A", ta phải tạo đối tượng của class "B" trước và truyền nó vào constructor của class "A", sau đó tạo đối tượng của class "C" và truyền nó vào constructor của class "B".

Trong trường hợp sử dụng IoC Container

Chúng ta có thể sử dụng reflection để tự động xác định sự phụ thuộc giữa các class và tạo đối tượng cho chúng một cách tự động. Chúng ta có thể gọi một hàm tạo đối tượng của class "A" trong IoC container và container sẽ tự động tạo đối tượng của class "B" và "C" cho chúng ta.

Điều này giúp ta giảm số lượng mã và giảm độ phức tạp của việc quản lý các sự phụ thuộc giữa các class.

Code ví dụ cụ thể

// Class C
class C {
    public function doSomething() {
        return 'This is class C';
    }
}

// Class B
class B {
    private $c;
    public function __construct(C $c) {
        $this->c = $c;
    }
    public function doSomething() {
        return $this->c->doSomething();
    }
}

// Class A
class A {
    private $b;
    public function __construct(B $b) {
        $this->b = $b;
    }
    public function doSomething() {
        return $this->b->doSomething();
    }
}

// Using without IoC Container
$c = new C();
$b = new B($c);
$a = new A($b);
echo $a->doSomething();

// Using with IoC Container and Reflection
class Container {
    private $bindings = [];
    public function bind($abstract, $concrete) {
        $this->bindings[$abstract] = $concrete;
    }
    public function make($abstract) {
        $concrete = $this->bindings[$abstract];
        $reflector = new ReflectionClass($concrete);
        if (!$reflector->isInstantiable()) {
            throw new Exception("Class $concrete cannot be instantiated");
        }
        $constructor = $reflector->getConstructor();
        if (is_null($constructor)) {
            return new $concrete;
        }
        $dependencies = $constructor->getParameters();
        $instances = $this->getDependencies($dependencies);
        return $reflector->newInstanceArgs($instances);
    }
    public function getDependencies($parameters) {
        $dependencies = [];
        foreach ($parameters as $parameter) {
            $dependency = $parameter->getClass();
            if (is_null($dependency)) {
                $dependencies[] = NULL;
            } else {
                $dependencies[] = $this->make($dependency->name);
            }
        }
        return $dependencies;
    }
}

$container = new Container();
$container->bind('A', 'A');
$container->bind('B', 'B');
$container->bind('C', 'C');
$a = $container->make('A');
echo $a->doSomething();

Kết quả:

This is class C
This is class C

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Back to top button
Close