php - 注入(inject)绑定(bind)到服务容器的实例

标签 php laravel laravel-5 ioc-container laravel-5.1

我有一个服务提供者,我想用它来将类的实例绑定(bind)到服务容器:

namespace App\Providers;

use Eluceo\iCal\Component\Calendar;
use Illuminate\Support\ServiceProvider;

class IcalProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->instance('iCal', function () {
            return new Calendar(config('calendar.name'));
        });
    }
}

据我了解the documentation on binding an instance ,这允许我将 key iCal 绑定(bind)到服务容器,以便稍后在我的 Controller 或服务类中我可以键入提示 iCal 并且在服务提供者中创建的实例将使用。

所以我创建了一个 Controller 并尝试输入提示我的实例:

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class CalendarInviteController extends Controller
{
    public function download(iCal $ical, $sessionId)
    {
        dd($ical);
    }
}

但是当我这样做时,我收到错误:

Class App\Http\Controllers\iCal does not exist

有道理,因为它在应用时会在 Controller 命名空间中查找不存在的名为 iCal 的类。由于 iCal 只是一个文本键,因此该实例没有 use 语句,因此我尝试告诉它查看根命名空间,认为可以修复它:

public function download(\iCal $ical, $sessionId)

我收到错误:

Class iCal does not exist

当我阅读文档中关于 resolving from the service container 的部分时看起来我在 Controller 中唯一需要做的就是输入提示来获取实例。

我是否误解了文档?

更新

我还应该提到,我确实将服务提供商添加到了我的 config/app.php 文件中。

此外,当我创建一个接口(interface)时,将其绑定(bind)到服务容器,编辑供应商代码来实现所述接口(interface),然后注入(inject)该接口(interface),它可以工作,但这需要我编辑供应商代码,但我不这样做想。

最佳答案

正如您在 docs 中看到的那样instance 方法采用一个键和一个对象实例来在容器中注册。所以,如果你想在容器中注册一个特定的实例,注册应该是:

namespace App\Providers;

use Eluceo\iCal\Component\Calendar;
use Illuminate\Support\ServiceProvider;

class IcalProvider extends ServiceProvider
{
    public function register()
    {
        //register a specific instance of the Calendar class in the container
        $this->app->instance('iCal', new Calendar(config('calendar.name') );
    }
}

这样你就可以通过以下方式取回实例:

 $cal = \App::make('iCal');

如果您的目的是在 Controller 方法中对类进行类型提示,并且您想要从服务容器解析先前注册的实例,您可以这样做:

namespace App\Providers;

use Eluceo\iCal\Component\Calendar;
use Illuminate\Support\ServiceProvider;

class IcalProvider extends ServiceProvider
{
    public function register()
    {
        //the key will be 'Eluceo\iCal\Component\Calendar'
        $this->app->instance( Calendar::class, new Calendar(config('calendar.name') );
    }
}

现在,在你的 Controller 中:

namespace App\Http\Controllers;

//important: specify the Calendar namespace
use Eluceo\iCal\Component\Calendar;

class CalendarInviteController extends Controller
{
    public function download(Calendar $ical, $sessionId)
    {
        dd($ical);
    }
}

这样,Laravel 将看到您想要一个 Calendar 对象,它会尝试从服务容器中获取它,查看是否存在该键的绑定(bind):(因为这是该类的命名空间您已在 Controller 中指定)

Eluceo\iCal\Component\Calendar

并且绑定(bind)存在!由于您已将此 key 绑定(bind)到服务提供商中的服务容器,因此 Laravel 将返回您注册的实例。

在您提供的代码中,您提示了类 iCal,但该类在任何地方都不存在,因此 Laravel 无法实例化该类

关于php - 注入(inject)绑定(bind)到服务容器的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32978106/

相关文章:

mysql - 如何将此 sql 查询写入 laravel 5 流畅的查询生成器?

php - 限制非管理员用户的路由访问

php - 多个foreach处理嵌套数组——PHP CodeIgniter

php - Symfony - 无法通过命令清除缓存

php - 如何处理上传和下载 PHP 生成的 CSV 文件

php - Laravel 5.1 中未找到类错误

laravel - 如何在 Laravel 应用程序中使用 npm 安装包?

laravel-5 - 在 Laravel 5.3.30 artisan 命令中不起作用

javascript - 如何使用 Drupal 创建输入数据?

excel - 函数 Maatwebsite\Excel\Excel::import() 的参数太少,1 个通过,至少 2 个预期