Laravel:构建Controller时无法实例化合同文件

问题描述

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

TECHPOOL-Create a Shopping Cart with Laravel 6

LARASHOUT-Laravel E-Commerce Application Development – Checkout

我能够在第一个网站上创建大多数购物车功能,但是它不涉及结帐和下订单,所以我找到了第二个网站。

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

Illuminate \ Contracts \ Container \ BindingResolutionException 构建[App \ Http \ Controllers \ CheckoutController]时,无法实例化目标[App \ Contracts \ OrderContract]。 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类,否则在尝试将其从容器中解决时会失败。所以这就是你应该做的:

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

  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()
    {
        //
    }
}

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