laravel 6 中策略类默认不通过容器解析,构造函数注入无效;需在 authserviceprovider 的 boot() 中用类名字符串注册策略(如 postpolicy::class),才能触发容器解析和依赖注入。

在 Laravel 6 中,授权策略(Policy)本身是普通 PHP 类,不经过服务容器自动解析——它默认由框架手动实例化,因此**构造函数注入不会自动生效**。但你仍可通过服务容器实现依赖注入,关键在于让策略类被容器管理,而非直接 new 实例。
策略类必须由容器解析才能触发依赖注入
Laravel 6 的策略授权机制(如 Gate::define 或 can() 方法)默认使用 new Policy() 方式创建实例,绕过了服务容器。要启用构造函数注入,需显式告诉 Gate:该策略应通过容器解析。
- 在
AuthServiceProvider的boot()方法中注册策略时,使用数组语法指定策略类名(字符串),而非匿名函数 - 确保策略类位于容器可自动解析的命名空间下(如
App\Policies),且构造函数参数类型提示清晰 - 若策略依赖接口(如
UserRepositoryInterface),必须提前在AppServiceProvider@register()中完成绑定
正确注册策略并启用容器解析
在 app/Providers/AuthServiceProvider.php 中:
public function boot()
{
$this->registerPolicies();
// ✅ 正确:传入类名字符串,Gate 会通过 app() 解析该类
Gate::resource('post', PostPolicy::class);
// 或自定义权限
Gate::define('update-post', [PostPolicy::class, 'update']);
}
此时,当 Gate 需要调用 PostPolicy@update 时,会通过 app(PostPolicy::class) 获取实例,从而触发构造函数注入。
策略类中使用构造函数注入示例
app/Policies/PostPolicy.php:
<?php namespace App\Policies;
use App\Models\Post;
use App\Models\User;
use App\Repositories\PostRepository;
use Illuminate\Auth\Access\HandlesAuthorization;
class PostPolicy
{
use HandlesAuthorization;
private $postRepository;
// ✅ 容器会自动注入 PostRepository 实例(前提是已绑定或可自动解析)
public function __construct(PostRepository $postRepository)
{
$this->postRepository = $postRepository;
}
public function update(User $user, Post $post)
{
return $user->id === $post->user_id
&& $this->postRepository->isEditable($post);
}
}
常见问题与修复
若遇到 Target [SomeInterface] is not instantiable 错误,说明容器无法解析某个依赖:
- 检查是否漏掉接口绑定,例如在
AppServiceProvider@register()中添加:$this->app->bind(PostRepositoryInterface::class, DbPostRepository::class); - 确认依赖类(如
PostRepository)自身构造函数的所有参数也都能被容器解析(无硬编码、无未绑定的类型提示) - 避免在策略中使用
app()->make()手动解析——这破坏解耦,且容易忽略生命周期问题











