我有一个服务提供者,我想用它来绑定一个类的实例到服务容器:
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'));
});
}
}
根据我对绑定实例的文档的理解,这允许我将键iCal
绑定到服务容器,以便稍后在我的控制器或服务类中我可以键入提示iCal
,并且将使用在服务提供者中创建的实例。
所以我创建了一个控制器并尝试键入hint my instance:
namespace App'Http'Controllers;
use App'Http'Controllers'Controller;
class CalendarInviteController extends Controller
{
public function download(iCal $ical, $sessionId)
{
dd($ical);
}
}
但是当我这样做的时候,我得到了错误:
类App'Http'Controllers'iCal不存在
是有意义的,因为它适用于在控制器命名空间中寻找一个名为iCal
的类,而这个类并不存在。没有使用语句的实例,因为iCal
只是一个文本键,所以我试着告诉它看根名称空间认为可能会修复它:
public function download('iCal $ical, $sessionId)
,我得到错误:
iCal类不存在
当我阅读文档中关于从服务容器解析的部分时,看起来我需要在控制器中做的唯一一件事就是输入提示来获取实例。
我是否误解了文档?
更新我还应该提到,我确实在我的config/app.php
文件中添加了我的服务提供商。
同样,当我创建一个接口时,将其绑定到服务容器,编辑供应商代码以实现该接口,并注入该接口,而不是它工作,但这需要我编辑我不想要的供应商代码。
正如您在文档中看到的,方法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');
如果你的目的是在控制器方法中提示类的类型,并且你想从服务容器中解析之前注册的实例,你可以这样做:
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') );
}
}
现在,在控制器中:
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
对象,它会尝试从服务容器中获取它,看看是否存在这个键的绑定:(因为这是你在控制器中指定的类的命名空间)
Eluceo'iCal'Component'Calendar
且绑定存在!因为你已经将这个密钥绑定到服务提供商的服务容器中,所以Laravel将返回你注册的实例。
在您提供的代码中,您提示了类iCal
,但该类在任何地方都不存在,因此Laravel无法实例化类
如果你想在你的控制器中注入依赖项(这很好,所以很好!),那么你需要一个接口名来提示类型。
通常你会有一个泛型接口,然后将该接口绑定到一个具体的实现。因此,您可能有一个日历服务接口,它绑定到您的iCal实现。像这样:use Eluceo'iCal'Component'Calendar;
class CalendarServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('App'Services'Calendar', function ($app) {
return new Calendar(config('calendar.name'));
});
}
public function provides()
{
return ['App'Services'Calendar'];
}
}
只要你在你的config/app.php文件中注册你的服务提供商,你现在就可以在类中输入提示你的日历依赖:
use App'Services'Calendar;
class InvitationController extends Controller
{
protected $calendar;
public function __construct(Calendar $calendar)
{
$this->calendar = $calendar;
}
}