Laravel: 构建控制器时合约文件不可实例化

Laravel: Contract file is not instantiable while building Controller

我正在尝试向我的 Laravel 应用程序添加购物车功能。我从 GitHub 安装了 darryldecode/laravelshoppingcart 软件包,并一直按照这两个网站中的说明进行操作。

TECHPOOL-Create a Shopping Cart with Laravel 6

LARASHOUT-Laravel E-Commerce Application Development – Checkout

我能够使用第一个网站创建大部分购物车功能,但它不包括结帐和下订单,所以我找到了第二个网站。

问题是合同文件不起作用。这是我得到的错误。

Illuminate\Contracts\Container\BindingResolutionException Target [App\Contracts\OrderContract] is not instantiable while building [App\Http\Controllers\CheckoutController]. http://localhost:8000/checkout

我在结帐过程中使用合同文件的地方在第二个网站中有解释。我对代码做了一些改动,以使其与第一个网站保持一致,但主要是我遵循了网站上的内容。

这是错误中提到的代码。

OrderContract.php

<?php

namespace App\Contracts;

interface OrderContract
{
    public function storeOrderDetails($params);
}

CheckoutController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Contracts\OrderContract;
use App\Http\Controllers\Controller;


class CheckoutController extends Controller
{
    protected $orderRepository;

    public function __construct(OrderContract $orderRepository)
    {
        $this->orderRepository = $orderRepository;
    }

    public function getCheckout()
    {
        return view('checkout');
    }

    public function placeOrder(Request $request)
    {
        // Before storing the order we should implement the
        // request validation which I leave it to you
        $order = $this->orderRepository->storeOrderDetails($request->all());

        dd($order);
    }
}

OrderRepository.php

<?php

namespace App\Repositories;

use Cart;
use App\Models\Order;
use App\Product;
use App\Models\OrderItem;
use App\Contracts\OrderContract;

class OrderRepository extends BaseRepository implements OrderContract
{
    public function __construct(Order $model)
    {
        parent::__construct($model);
        $this->model = $model;
    }

    public function storeOrderDetails($params)
    {
        $order = Order::create([
            'order_number'      =>  'ORD-' . strtoupper(uniqid()),
            'status'            =>  'pending',
            'grand_total'       =>  Cart::getSubTotal(),
            'item_count'        =>  Cart::getTotalQuantity(),
            'table_number'      =>  $params['table_number'],
            'name'              =>  $params['name'],
            'notes'             =>  $params['notes']
        ]);

        if ($order) {

            $items = Cart::getContent();

            foreach ($items as $item) {
                // A better way will be to bring the product id with the cart items
                // you can explore the package documentation to send product id with the cart
                $product = Product::where('name', $item->name)->first();

                $orderItem = new OrderItem([
                    'product_id'    =>  $product->id,
                    'quantity'      =>  $item->quantity,
                    'price'         =>  $item->getPriceSum()
                ]);

                $order->items()->save($orderItem);
            }
        }

        return $order;
    }
}

RepositoryServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Contracts\OrderContract;
use App\Repositories\OrderRepository;

class RepositoryServiceProvider extends ServiceProvider
{
    protected $repositories = [
        OrderContract::class            =>          OrderRepository::class,
    ];

    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        foreach ($this->repositories as $interface => $implementation) {
            $this->app->bind($interface, $implementation);
        }
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

我不是很熟悉合约概念,因为我最近才开始学习 Laravel,我完全迷失在这里。也许问题是我没有创建另一个必要的文件或其他文件。

任何帮助将不胜感激,因为我尝试了多种方法都没有成功。

提前致谢。

是的,这是预料之中的……你的合约应该指向一个 Solid class 否则它会在尝试从容器中解析它时失败。所以这是你应该做的:

  1. 创建一个实现该特征的 class。

  2. 转到您的 AppServiceProvider 并将其绑定到该合同,如下所示:

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
        $this->app->bind(\App\Contracts\OrderContract::class, App\Repositories\ClassImplementingOrderContract::class);
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

这应该可以解决您的问题。

即使您忘记将“RepositoryServiceProvider”添加到“config/app.php”的 serviceProviders 数组中,也可能会导致此错误。