2023. 3. 17. 19:20ㆍPHP
서비스컨테이너(serviceContainer)란 객체를 생성하고 의존성 주입을 처리하는데 사용되는 라라벨의 기본 구성 요소입니다. 서비스 컨테이너는 라라벨 어플리케이션의 모든 객체를 인스턴스화하고 필요한 객체 간의 의존성을 자동으로 해결합니다. 이러한 기능을 수행하기 위해, 서비스 컨테이너는 객체의 클래스 이름과 생성 방법 등의 정보를 가지고 있습니다.
서비스프로바이더(serviceProvider)란 서비스 컨테이너에게 객체 생성 및 등록을 수행하는 역할을 합니다. 즉, 서비스 프로바이더는 라라벨 어플리케이션에 필요한 서비스들을 등록하고, 서비스 컨테이너가 이를 인스턴스화하고 의존성 주입을 처리할 수 있도록 지원합니다.
서비스 프로바이더는 서비스 컨테이너의 동작을 제어하는 데 사용되는 라라벨의 확장 기능입니다.
서비스 프로바이더를 사용하면, 라라벨 어플리케이션에서 필요한 서비스들을 중앙 집중적으로 관리하고,
유지보수성을 높일 수 있습니다.
정리하면 라라벨의 의존성 주입 기능을 구현하는 데 필요한 두 가지 다른 개념이며 서비스 컨테이너는 객체를 생성하고 의존성 주입을 처리하는 데 사용되며, 서비스 프로바이더는 서비스 컨테이너에게 객체 등록을 수행하는 데 사용됩니다.
아래 실제 사용되는 코드로 예시를 설명하겠습니다.
// app/Interfaces/DatabaseInterface.php
<?php
namespace App\Interfaces;
interface DatabaseInterface {
public function connect();
public function query($sql);
}
// app/Services/MySQLDatabase.php
<?php
namespace App\Services;
use App\Interfaces\DatabaseInterface;
class MySQLDatabase implements DatabaseInterface {
public function connect() {
// connect to MySQL database
}
public function query($sql) {
// execute query on MySQL database
}
}
// app/Services/PostgresDatabase.php
<?php
namespace App\Services;
use App\Interfaces\DatabaseInterface;
class PostgresDatabase implements DatabaseInterface {
public function connect() {
// connect to Postgres database
}
public function query($sql) {
// execute query on Postgres database
}
}
// app/Providers/DatabaseServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Interfaces\DatabaseInterface;
use App\Services\MySQLDatabase;
use App\Services\PostgresDatabase;
class DatabaseServiceProvider extends ServiceProvider {
public function register() {
$this->app->bind(DatabaseInterface::class, function($app) {
$dbDriver = config('database.default');
if ($dbDriver == 'mysql') {
return new MySQLDatabase();
} else if ($dbDriver == 'pgsql') {
return new PostgresDatabase();
}
});
}
}
// config/app.php
return [
// ...
'providers' => [
// ...
App\Providers\DatabaseServiceProvider::class,
],
// ...
];
// app/Http/Controllers/UserController.php
<?php
namespace App\Http\Controllers;
use App\Interfaces\DatabaseInterface;
class UserController extends Controller {
protected $database;
public function __construct(DatabaseInterface $database) {
$this->database = $database;
}
public function getAllUsers() {
$sql = "SELECT * FROM users";
return $this->database->query($sql);
}
}
위 코드로 실행하게 되면 MySQLDatabase 또는 PostgresDatabase 인스턴스를 수동으로 생성할 필요없이 서비스 컨테이너가 앞서 정의한 DatabaseServiceProvider를 사용하여 DatabaseInterface의 인스턴스를 자동으로 해결합니다. 만약 `config/database.php` 의 default가 'mysq'로 있으면 MySQLDatabase 인스턴스로 할당 되겠네요.
추가로 서비스 컨테이너의 작동 방식과 장점을 설명하겠습니다.
작동방식 :
1. Laravel이 부팅되면 config/app.php 구성 파일에 정의된 모든 서비스 공급자를 등록합니다.
2. DatabaseServiceProvider는 그러한 공급자 중 하나이며 config/database.php에 지정된 구성을 기반으로 DatabaseInterface를 구체적인 구현(MySQLDatabase 또는 PostgresDatabase) 중 하나에 바인딩하는 역할을 합니다.
3. UserController는 DatabaseInterface에 의존하므로 서비스 컨테이너는 DatabaseServiceProvider에서 해당 인터페이스에 대한 바인딩을 찾습니다.
4. config/database.php의 구성에 따라 서비스 컨테이너는 MySQLDatabase 또는 PostgresDatabase의 인스턴스를 확인하고 이를 UserController 생성자에 주입합니다.
5. 마지막으로 UserController에서 getAllUsers 메서드를 호출하여 데이터베이스에서 모든 사용자를 가져올 수 있습니다.
장점 :
1. 위와 같은 코드를 활용하면 다른 컨트롤러에서 MySQLDatabase 클래스를 선언 시 새로운 메모리에 할당하는게 아니라 이미 할당되어져있는 MySQLDatabase를 불러와서 재사용하여 메모리 활용을 효율적으로 하는 장점이 있습니다.
2. 위 코드는 DIP(위존성 역전 원칙)을 이용하였기 때문에 코드의 확장성과 유지보수성이 좋습니다.
'PHP' 카테고리의 다른 글
[Laravel] beginTransaction, lockForUpdate 활용 (일관성, 동시성) with. ORM (0) | 2024.08.12 |
---|---|
DTO DAO 정리 with 라라벨 (0) | 2023.04.21 |
라라벨 가바지 컬렉션 처리 (0) | 2023.03.17 |
Eloquent ORM 이란 (0) | 2022.12.14 |
static 정의 (0) | 2022.03.04 |