class UserService {
public function getUser($id) {
return "User #" . $id;
}
}
class Logger {
public function log($msg) {
echo "[LOG] $msg\n";
}
}
class UserController {
// method injection
public function show(UserService $service, Logger $logger, $id) {
$user = $service->getUser($id);
$logger->log("Fetched user");
return $user;
}
}
class Container {
public function make($class) {
return new $class();
}
public function call($callable, $params = []) {
// $callable = [object, 'method']
$reflection = new ReflectionMethod($callable[0], $callable[1]);
$dependencies = [];
foreach ($reflection->getParameters() as $param) {
$type = $param->getType();
if ($type && !$type->isBuiltin()) {
// resolve class
$dependencies[] = $this->make($type->getName());
} else {
// lấy từ params truyền vào (route param kiểu Laravel)
$name = $param->getName();
$dependencies[] = $params[$name] ?? null;
}
}
return $reflection->invokeArgs($callable[0], $dependencies);
}
}
$container = new Container(); $controller = $container->make(UserController::class); // giả lập route param $params = ['id' => 123]; $result = $container->call([$controller, 'show'], $params); echo $result;
👉 Output:
[LOG] Fetched user User #123
| Loại param | Resolve kiểu gì |
|---|---|
| Class type-hint | Container new + inject |
| Scalar (id, slug...) | Lấy từ input (route, request) |
=> Đây chính là cách Laravel làm:
$container->call([$controller, 'method'], $routeParams);
| Constructor DI | Method DI |
|---|---|
Inject lúc new | Inject lúc call method |
| Luôn tồn tại | Chỉ dùng khi cần |
| Dùng cho dependency "core" | Dùng cho dependency "runtime" |
👉 Flow chuẩn:
Router → Container->make(Controller)
→ Container->call(method, params)