Laravel 13 服务容器详解
摘要
Laravel 的服务容器是管理类依赖和执行依赖注入的强大工具。本文将深入讲解 Laravel 13 的服务容器,包括:
- 服务绑定与解析
- 依赖注入
- 接口绑定
- 上下文绑定
- 实战案例与最佳实践
本文适合希望掌握服务容器的 Laravel 开发者。
1. 基本概念
1.1 什么是服务容器
服务容器是一个用于管理类依赖和执行依赖注入的工具。它可以帮助你:
1.2 获取容器实例
1 2 3 4
| use Illuminate\Container\Container;
$container = app(); $container = Container::getInstance();
|
2. 服务绑定
2.1 简单绑定
1 2 3 4 5
| use App\Services\PaymentService;
app()->bind(PaymentService::class, function ($app) { return new PaymentService(); });
|
2.2 单例绑定
1 2 3
| app()->singleton(PaymentService::class, function ($app) { return new PaymentService(); });
|
2.3 实例绑定
1 2
| $service = new PaymentService(); app()->instance(PaymentService::class, $service);
|
2.4 绑定原始值
1 2 3
| app()->when('App\Http\Controllers\UserController') ->needs('$apiKey') ->give(env('API_KEY'));
|
3. 服务解析
3.1 使用 make 方法
1
| $service = app()->make(PaymentService::class);
|
3.2 使用 resolve 方法
1
| $service = resolve(PaymentService::class);
|
3.3 使用 app 辅助函数
1
| $service = app(PaymentService::class);
|
3.4 自动注入
1 2 3 4 5 6 7 8 9
| use App\Services\PaymentService;
class OrderController extends Controller { public function store(PaymentService $payment) { } }
|
4. 接口绑定
4.1 定义接口
1 2 3 4 5 6 7 8
| <?php
namespace App\Contracts;
interface PaymentInterface { public function process(float $amount): bool; }
|
4.2 实现接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?php
namespace App\Services;
use App\Contracts\PaymentInterface;
class StripePayment implements PaymentInterface { public function process(float $amount): bool { return true; } }
|
4.3 绑定接口到实现
1 2 3 4 5 6 7 8
| use App\Contracts\PaymentInterface; use App\Services\StripePayment;
public function register(): void { $this->app->bind(PaymentInterface::class, StripePayment::class); }
|
4.4 使用接口
1 2 3 4 5 6 7 8 9
| use App\Contracts\PaymentInterface;
class OrderController extends Controller { public function store(PaymentInterface $payment) { $payment->process(100.00); } }
|
5. 上下文绑定
5.1 基本用法
1 2 3 4 5 6 7 8 9 10 11
| use App\Contracts\PaymentInterface; use App\Services\StripePayment; use App\Services\PayPalPayment;
app()->when(OrderController::class) ->needs(PaymentInterface::class) ->give(StripePayment::class);
app()->when(SubscriptionController::class) ->needs(PaymentInterface::class) ->give(PayPalPayment::class);
|
5.2 闭包绑定
1 2 3 4 5
| app()->when(OrderController::class) ->needs(PaymentInterface::class) ->give(function ($app) { return new StripePayment(config('services.stripe')); });
|
6. 标签绑定
6.1 定义标签
1 2 3 4
| app()->bind('report.csv', CsvReporter::class); app()->bind('report.pdf', PdfReporter::class);
app()->tag(['report.csv', 'report.pdf'], 'reports');
|
6.2 解析标签
1 2 3 4 5
| $reports = app()->tagged('reports');
foreach ($reports as $report) { $report->generate(); }
|
7. 实战案例
7.1 支付服务绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider; use App\Contracts\PaymentInterface; use App\Services\StripePayment; use App\Services\PayPalPayment;
class PaymentServiceProvider extends ServiceProvider { public function register(): void { $this->app->bind(PaymentInterface::class, function ($app) { $provider = config('payment.default'); return match ($provider) { 'stripe' => new StripePayment(config('services.stripe')), 'paypal' => new PayPalPayment(config('services.paypal')), default => throw new \Exception('Invalid payment provider'), }; }); } }
|
7.2 仓储模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider; use App\Contracts\UserRepositoryInterface; use App\Repositories\EloquentUserRepository;
class RepositoryServiceProvider extends ServiceProvider { public function register(): void { $this->app->bind(UserRepositoryInterface::class, EloquentUserRepository::class); } }
|
8. 最佳实践
8.1 使用接口
1 2 3 4 5
| public function __construct(PaymentInterface $payment) {}
public function __construct(StripePayment $payment) {}
|
8.2 在服务提供者中绑定
1 2 3 4 5 6 7 8
| class AppServiceProvider extends ServiceProvider { public function register(): void { $this->app->bind(Service::class, Implementation::class); } }
|
9. 总结
Laravel 的服务容器提供了强大的依赖注入能力:
- 服务绑定:灵活的绑定方式
- 自动解析:自动注入依赖
- 接口绑定:解耦接口与实现
- 上下文绑定:按需注入不同实现
参考资料