Laravel Service Container零配置解决自动注入失败

问题描述 投票:0回答:1

我最近刚刚开始学习 Laravel,并决定通过实践来学习。

据我从文档中了解到的[示例:1][示例:2]我可以在构造函数中键入提示属性以进行自动注入。

因此,为了尝试这一点,我决定重做微风脚手架的用户注册控制器,使其更加清晰,并将验证和所有逻辑提取到服务中。

class RegisteredUserController extends Controller
{
  protected UserService $userService;

  public function __construct(UserService $userService)
  {
  }

  public function store(RegisterUserRequest $request): RedirectResponse
  {
    $this->userService->create($request->validated());

    return redirect(route('dashboard', absolute: false));
  }
}

服务非常简单,我只是从控制器的操作中复制粘贴默认代码:

class UserService
{
/**
 * @param RegisterUserRequest $request
 * @return void
 */
public function create(RegisterUserRequest $request): void
{
    $user = User::create([
        'name' => $request['name'],
        'email' => $request['email'],
        'password' => Hash::make($request['password']),
        'age' => $request['age'],
    ]);

    event(new Registered($user));

    Auth::login($user);
}

到目前为止,这都是有趣的游戏,一切都按预期进行。所以我决定继续使用相同的模式,我讨厌臃肿的控制器,即使第一个方法可能不需要调用服务。但我计划添加更多。

class HousingService
{
  /**
   * @return Collection
   */
  public function list(): Collection
  {
    return Housing::all();
  }
}

我希望你还在我身边,抱歉让你拖了这么久。但我们现在正在解决这个问题。

当我尝试使用相同的方法将依赖的 HousingService 类注入到 HousingController 中时,我收到一条错误,提示我正在尝试在初始化之前访问类型化属性。

初始化之前不得访问类型化属性 App\Http\Controllers\HousingController::$housingService

这就是有问题的控制器。我完全不知道这两者有什么区别。

class HousingController extends Controller
{
  protected HousingService $housingService;

  public function __construct(HousingService $housingService)
  {
    //if i type the commented code below it fixes the error, but 
    //i'd like to know what's causing it, since it wasn't required 
    //before

    //$this->housingService = $housingService
  }

  public function list(Request $request)
  {
    return view('housing.list', [
        'user' => $request->user(),
        'housings' => $this->housingService->list(),
    ]);
  }
}

感谢您对我的包容,希望我不是一个绝对的白痴,因为错过了一些非常简单的东西。

php laravel dependency-injection dependency-resolution laravel-service-container
1个回答
0
投票

您似乎将依赖注入与 OOP 混淆了。 DI 仅用于根据类型提示的类自动构建所需的对象,并将它们注入到当前方法中。您如何处理方法/类中的构建对象取决于您。

protected HousingService $housingService;

public function __construct(HousingService $housingService)
{
    // here $housingService is the injected object from DI
    // this injected object has nothing to do with the properties of the class
    // $this->housingService is a property of the class and since you have not given it a default value it is an undefined property
    // so $this->housingService and $housingService are not the same
    // it is up to you to assign the property to the injected object
    $this->housingService = $housingService
}

如果你不想写出来,较短的语法版本是:

public function __construct(protected HousingService $housingService)
{}

请记住,这只是语法糖,其功能与第一个版本相同。

© www.soinside.com 2019 - 2024. All rights reserved.