在 class 上注入接口(Laravel 包)
Injecting Interface on class (Laravel Package)
我正在开发自己的 L5 包来处理付款。为了将来能够更改支付网关,我正在使用接口。
我的界面是这样的:
interface BillerInterface
{
public function payCash();
public function payCreditCard();
}
我也有一个具体的实现,就是想要的支付网关
class Paypal implements BillerInterface
{
public function payCash()
{
// Logic
}
public function payCreditCard()
{
// Logic
}
}
Biller class 是主要的 class,构造函数方法需要上述接口,如下所示:
class Biller {
protected $gateway;
public function __construct(BillerInterface $gateway)
{
$this->gateway = $gateway;
}
// Logic
}
最后,我创建了服务提供者,将接口绑定到网关 class。
public function register()
{
$this->app->bind(BillerInterface::class, 'Vendor\Biller\Gateways\Paypal');
}
似乎可以正常工作,但我在尝试实例化 Biller 时遇到错误 class...
Biller::__construct() must be an instance of Vendor\Biller\Contracts\BillerInterface, none given
我尝试了以下代码,但似乎不起作用...
public function register()
{
$this->app->bind(BillerInterface::class, 'Vendor\Biller\Gateways\Paypal');
$this->app->bind(Biller::class, function ($app) {
return new Biller($app->make(BillerInterface::class));
});
}
有什么线索吗?
当您将接口绑定到实际 class 时,请尝试将 BillerInterface::class
替换为字符串“\Your\Namespace\BillerInterface”
这是我在我的应用程序中完成的方法,它似乎有效:
public function register()
{
$this->app->bind('DesiredInterface', function ($app) {
return new DesiredImplementationClass(
$app['em'],
new ClassMetaData(DesiredClass::class)
);
});
}
您正在将接口绑定到服务提供商中的实现。但是依赖只会被服务容器解决,即
class SomeClass
{
public function __construct(Billing $billing)
{
$this->billing = $billing;
}
}
Laravel 的服务容器将读取构造方法参数的类型提示,并解析该实例(以及它的任何依赖项)。
您将无法直接“新建”Billing
实例(即 $billing = new Billing
),因为构造函数期望实现 BillingInterface
,而您没有提供。
谈论 @MaGnetas
回答
我更喜欢使用这种方式将 class 与界面绑定。
public function register()
{
$this->app->bind(AppointmentInterface::class, AppointmentService::class);
}
这有助于 IDE 找到 class 的路径,我们只需单击它就可以跳转到 class。
如果我们将 class 路径作为字符串路径传递,如下所示:
public function register()
{
$this->app->bind('App\Interfaces\AppointmentInterface', 'App\Services\AppointmentService');
}
然后IDE在我们点击这个字符串的时候找不到class的位置
我正在开发自己的 L5 包来处理付款。为了将来能够更改支付网关,我正在使用接口。
我的界面是这样的:
interface BillerInterface
{
public function payCash();
public function payCreditCard();
}
我也有一个具体的实现,就是想要的支付网关
class Paypal implements BillerInterface
{
public function payCash()
{
// Logic
}
public function payCreditCard()
{
// Logic
}
}
Biller class 是主要的 class,构造函数方法需要上述接口,如下所示:
class Biller {
protected $gateway;
public function __construct(BillerInterface $gateway)
{
$this->gateway = $gateway;
}
// Logic
}
最后,我创建了服务提供者,将接口绑定到网关 class。
public function register()
{
$this->app->bind(BillerInterface::class, 'Vendor\Biller\Gateways\Paypal');
}
似乎可以正常工作,但我在尝试实例化 Biller 时遇到错误 class...
Biller::__construct() must be an instance of Vendor\Biller\Contracts\BillerInterface, none given
我尝试了以下代码,但似乎不起作用...
public function register()
{
$this->app->bind(BillerInterface::class, 'Vendor\Biller\Gateways\Paypal');
$this->app->bind(Biller::class, function ($app) {
return new Biller($app->make(BillerInterface::class));
});
}
有什么线索吗?
当您将接口绑定到实际 class 时,请尝试将 BillerInterface::class
替换为字符串“\Your\Namespace\BillerInterface”
这是我在我的应用程序中完成的方法,它似乎有效:
public function register()
{
$this->app->bind('DesiredInterface', function ($app) {
return new DesiredImplementationClass(
$app['em'],
new ClassMetaData(DesiredClass::class)
);
});
}
您正在将接口绑定到服务提供商中的实现。但是依赖只会被服务容器解决,即
class SomeClass
{
public function __construct(Billing $billing)
{
$this->billing = $billing;
}
}
Laravel 的服务容器将读取构造方法参数的类型提示,并解析该实例(以及它的任何依赖项)。
您将无法直接“新建”Billing
实例(即 $billing = new Billing
),因为构造函数期望实现 BillingInterface
,而您没有提供。
谈论 @MaGnetas
回答
我更喜欢使用这种方式将 class 与界面绑定。
public function register()
{
$this->app->bind(AppointmentInterface::class, AppointmentService::class);
}
这有助于 IDE 找到 class 的路径,我们只需单击它就可以跳转到 class。
如果我们将 class 路径作为字符串路径传递,如下所示:
public function register()
{
$this->app->bind('App\Interfaces\AppointmentInterface', 'App\Services\AppointmentService');
}
然后IDE在我们点击这个字符串的时候找不到class的位置