Laravel Contract
简介
Laravel的Contract是一组定义框架提供的核心服务的接口。例如,Illuminate\Contracts\Queue\Queue
Contract 定义了排队作业所需的方法,而Illuminate\Contracts\Mail\Mailer
Contract 定义了发送电子邮件所需的方法。
对每个Contract,框架都有提供的相应实现。例如,Laravel提供了具有各种驱动程序的队列实现,以及由SwiftMailer提供支持的邮件程序的实现。
所有Laravel Contract都存在于自己的GitHub仓库中。
Contract 与 Facade
Laravel的Facade 和帮助功能提供了一种利用Laravel服务的简单方法,而无需在方法的参数中键入类型限定,就可以从服务容器中解析Contract。在大多数情况下,每个Facade都有一个等效的Contract。
与Facade(不需要您在类的构造函数中传入Facade)不同,Contract允许我们为类定义显式依赖关系。一些开发人员更喜欢以这种方式显式定义其依赖项,因此他们更喜欢使用Contract,而其他开发人员则享受Facade的便利。
无论是喜欢Facade还是Contract这都没关系,大多数的应用程序都能正常运行。但是,如果要构建程序包,则应强烈考虑使用Contract,因为它们在程序包上下文中更容易测试。
何时使用 Contract
如在其他地方讨论的那样,使用Contract或Facade的许多决定将取决于个人喜好和开发团队的喜好。Contract和Facade均可用于创建功能强大且经过良好测试的Laravel应用程序。只要保持类的职责单一,就会发现使用Contract和Facade之间的实际差异很小。
但是,我们可能仍然对Contract有几个疑问。例如,为什么要完全使用接口?使用接口不是更复杂吗?让我们将使用接口的原因归纳为以下两点:松散耦合和简单性。
松耦合
首先,让我们回顾一些与缓存实现紧密相关的代码:
<?php
namespace App\Orders;
class Repository
{
/**
* The cache instance.
*/
protected $cache;
/**
* Create a new repository instance.
*
* @param \SomePackage\Cache\Memcached $cache
* @return void
*/
public function __construct(\SomePackage\Cache\Memcached $cache)
{
$this->cache = $cache;
}
/**
* Retrieve an Order by ID.
*
* @param int $id
* @return Order
*/
public function find($id)
{
if ($this->cache->has($id)) {
//
}
}
}
在此类中,代码与给定的缓存实现紧密耦合。之所以紧密耦合,是因为我们依赖于软件包 provider 提供的具体Cache类。如果该包的API更改,我们的代码也必须更改。
同样,如果我们要用另一种技术(Redis)替换我们的基础缓存技术(Memcached),则我们将不得不再次修改代码。我们的Repository不应该过多的关系是谁提供数据或他们是如何提供数据的。
要替换这种方法,我们可以依靠简单的,与实现无关的接口来改进代码:
<?php
namespace App\Orders;
use Illuminate\Contracts\Cache\Repository as Cache;
class Repository
{
/**
* The cache instance.
*/
protected $cache;
/**
* Create a new repository instance.
*
* @param Cache $cache
* @return void
*/
public function __construct(Cache $cache)
{
$this->cache = $cache;
}
}
现在,该代码尚未耦合到任何特定的实现,由于Contract包不包含任何实现且没有依赖关系,因此我们可以轻松地编写任何给定Contract的替代实现,从而使我们可以替换缓存的实现,而无需修改任何调用缓存的代码。
如何使用 Contract
那么,如何获得Contract的实现?实际上很简单。
Laravel中的许多类型的类都可以通过服务容器来解析,包括控制器,事件监听器,中间件,排队的作业,甚至路由闭包。因此,要获取Contract的实现,我们只需在要解析的类的构造函数中输入该接口的“类型提示”即可。
例如:
<?php
namespace App\Listeners;
use App\Events\OrderWasPlaced;
use App\User;
use Illuminate\Contracts\Redis\Factory;
class CacheOrderInformation
{
/**
* The Redis factory implementation.
*/
protected $redis;
/**
* Create a new event handler instance.
*
* @param Factory $redis
* @return void
*/
public function __construct(Factory $redis)
{
$this->redis = $redis;
}
/**
* Handle the event.
*
* @param OrderWasPlaced $event
* @return void
*/
public function handle(OrderWasPlaced $event)
{
//
}
}
解析事件监听器后,服务容器将读取类的构造函数上的类型提示,并注入适当的值。要了解有关在服务容器中注册内容的更多信息,请查阅服务容器文档。
Contract 参考
下表提供了所有Laravel Contract 及其等效Facade的参考:
Contract | References Facade |
---|---|
Illuminate\Contracts\Auth\Access\Authorizable | |
Illuminate\Contracts\Auth\Access\Gate | Gate |
Illuminate\Contracts\Auth\Authenticatable | |
Illuminate\Contracts\Auth\CanResetPassword | |
Illuminate\Contracts\Auth\Factory | Auth |
Illuminate\Contracts\Auth\Guard | Auth::guard() |
Illuminate\Contracts\Auth\PasswordBroker | Password::broker() |
Illuminate\Contracts\Auth\PasswordBrokerFactory | Password |
Illuminate\Contracts\Auth\StatefulGuard | |
Illuminate\Contracts\Auth\SupportsBasicAuth | |
Illuminate\Contracts\Auth\UserProvider | |
Illuminate\Contracts\Bus\Dispatcher | Bus |
Illuminate\Contracts\Bus\QueueingDispatcher | Bus::dispatchToQueue() |
Illuminate\Contracts\Broadcasting\Factory | Broadcast |
Illuminate\Contracts\Broadcasting\Broadcaster | Broadcast::connection() |
Illuminate\Contracts\Broadcasting\ShouldBroadcast | |
Illuminate\Contracts\Broadcasting\ShouldBroadcastNow | |
Illuminate\Contracts\Cache\Factory | Cache |
Illuminate\Contracts\Cache\Lock | |
Illuminate\Contracts\Cache\LockProvider | |
Illuminate\Contracts\Cache\Repository | Cache::driver() |
Illuminate\Contracts\Cache\Store | |
Illuminate\Contracts\Config\Repository | Config |
Illuminate\Contracts\Console\Application | |
Illuminate\Contracts\Console\Kernel | Artisan |
Illuminate\Contracts\Container\Container | App |
Illuminate\Contracts\Cookie\Factory | Cookie |
Illuminate\Contracts\Cookie\QueueingFactory | Cookie::queue() |
Illuminate\Contracts\Database\ModelIdentifier | |
Illuminate\Contracts\Debug\ExceptionHandler | |
Illuminate\Contracts\Encryption\Encrypter | Crypt |
Illuminate\Contracts\Events\Dispatcher | Event |
Illuminate\Contracts\Filesystem\Cloud | Storage::cloud() |
Illuminate\Contracts\Filesystem\Factory | Storage |
Illuminate\Contracts\Filesystem\Filesystem | Storage::disk() |
Illuminate\Contracts\Foundation\Application | App |
Illuminate\Contracts\Hashing\Hasher | Hash |
Illuminate\Contracts\Http\Kernel | |
Illuminate\Contracts\Mail\MailQueue | Mail::queue() |
Illuminate\Contracts\Mail\Mailable | |
Illuminate\Contracts\Mail\Mailer | |
Illuminate\Contracts\Notifications\Dispatcher | Notification |
Illuminate\Contracts\Notifications\Factory | Notification |
Illuminate\Contracts\Pagination\LengthAwarePaginator | |
Illuminate\Contracts\Pagination\Paginator | |
Illuminate\Contracts\Pipeline\Hub | |
Illuminate\Contracts\Pipeline\Pipeline | |
Illuminate\Contracts\Queue\EntityResolver | |
Illuminate\Contracts\Queue\Factory | Queue |
Illuminate\Contracts\Queue\Job | |
Illuminate\Contracts\Queue\Monitor | Queue |
Illuminate\Contracts\Queue\Queue | Queue::connection() |
Illuminate\Contracts\Queue\QueueableCollection | |
Illuminate\Contracts\Queue\QueueableEntity | |
Illuminate\Contracts\Queue\ShouldQueue | |
Illuminate\Contracts\Redis\Factory | Redis |
Illuminate\Contracts\Routing\BindingRegistrar | Route |
Illuminate\Contracts\Routing\Registrar | Route |
Illuminate\Contracts\Routing\ResponseFactory | Response |
Illuminate\Contracts\Routing\UrlGenerator | URL |
Illuminate\Contracts\Routing\UrlRoutable | |
Illuminate\Contracts\Session\Session | Session::driver() |
Illuminate\Contracts\Support\Arrayable | |
Illuminate\Contracts\Support\Htmlable | |
Illuminate\Contracts\Support\Jsonable | |
Illuminate\Contracts\Support\MessageBag | |
Illuminate\Contracts\Support\MessageProvider | |
Illuminate\Contracts\Support\Renderable | |
Illuminate\Contracts\Support\Responsable | |
Illuminate\Contracts\Translation\Loader | |
Illuminate\Contracts\Translation\Translator | Lang |
Illuminate\Contracts\Validation\Factory | Validator |
Illuminate\Contracts\Validation\ImplicitRule | |
Illuminate\Contracts\Validation\Rule | |
Illuminate\Contracts\Validation\ValidatesWhenResolved | |
Illuminate\Contracts\Validation\Validator | Validator::make() |
Illuminate\Contracts\View\Engine | |
Illuminate\Contracts\View\Factory | View |
Illuminate\Contracts\View\View | View::make() |