如何在Laravel 5(5.2)中的另一个存储库类上注入存储库

时间:2016-04-04 04:11:54

标签: php laravel dependency-injection laravel-5.2

假设我有两个实现契约的存储库(UserRepository,RoleRepository)(UserRepositoryInterface,RoleRepositoryInterface)。

我想要做的是将RoleRepository注入UserRepository的构造函数方法,我一直在努力使这个工作,但我收到了这个错误:

  

构建[App \ Http \ Controllers \ UserController]时,目标[App \ Contracts \ UserRepositoryInterface]无法实例化。

这是我到目前为止所得到的,

composer.json

"require": {
    "php": ">=5.5.9",
    "laravel/framework": "5.2.*",
    "tymon/jwt-auth": "^0.5.9",
    "zizaco/entrust": "dev-laravel-5"
},
"require-dev": {
    "fzaninotto/faker": "~1.4",
    "mockery/mockery": "^0.9.4",
    "phpunit/phpunit": "~4.0",
    "symfony/css-selector": "2.8.*|3.0.*",
    "symfony/dom-crawler": "2.8.*|3.0.*"
},
"autoload": {
    "classmap": [
        "database"
    ],
    "psr-4": {
        "App\\": "app/",
        "App\\Models\\": "app/Models/",
        "App\\Contracts\\": "app/Contracts/",
        "App\\Repositories\\": "app/Repositories/"
    }
},
"autoload-dev": {
    "classmap": [
        "tests/TestCase.php",
        "tests/MockData.php"
    ]
}

配置/ app.php

'providers' => [

    /*
     * Laravel Framework Service Providers...
     */
    ...

    /**
     * Third-party Service Providers
     */
    ...

    /*
     * Application Service Providers...
     */
    ...

    /**
     * Custom Service Providers...
     */
    App\Providers\RepositoryServiceProvider::class,

应用程序/提供者/ RepositoryServiceProvider.php     

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class RepositoryServiceProvider extends ServiceProvider
{
    public function register()
    {
        $models = [
            'Role',
            'User',
        ];

        foreach ($models as $model) {
            $this->app->bind(
                "App\Contracts\\{$model}Interface",
                "App\Repositories\\{$model}Repository"
            );
        }
    }
}

应用程序/控制器/ UserController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Contracts\UserRepositoryInterface as UserRepository;

class UserController extends Controller
{

    /**
     * @var UserRepository
     */
    private $repo;

    /**
     * Class constructor
     *
     * @param UserRepository $repo
     */
    public function __construct(
        UserRepository $repo
    ) {
        $this->repo = $repo;
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function store(Request $request)
    {
        $data = $request->all();

        $user = $this->repo->store($data);

        return response()->json($user, 201);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function update(Request $request, $id)
    {
        $data = $request->all();

        $user = $this->repo->store($data, $id);

        return response()->json($data, 200);
    }

应用程序/合同/ RoleRepositoryInterface.php

<?php

namespace App\Contracts;

interface RoleRepositoryInterface
{
    /**
     * Attach role to user
     *
     * @param  static $user
     * @param  string $roleName
     *
     * @return static
     */
    public function role($user, $roleName);

}

应用程序/合同/ UserRepositoryInterface.php

<?php

namespace App\Contracts;

interface UserRepositoryInterface
{

    /**
     * Create new or update an existing user
     *
     * @param  array  $data
     * @param  int    $id
     *
     * @return bool|int|array
     */
    public function store(array $data, $id = null);
}

应用程序/库/ RoleRepository.php

<?php

namespace App\Repositories;

use InvalidArgumentException;

use App\Contracts\RoleRepositoryInterface;
use App\Models\Role;

class RoleRepository extends Role implements RoleRepositoryInterface
{

    /**
     * Attach a role to user
     *
     * @param  static $user
     * @param  string $roleName
     *
     * @return static
     *
     * @throws \InvalidArgumentException
     */
    public function attachRole($user, $roleName)
    {
        if (!$user instanceof App\Models\User::class) {
            throw new InvalidArgumentException("{$user} must be an instance of App\Models\User");
        }

        // find role
        $role = $this->where('name', $roleName)->first();

        // attach role to user
        $user->attachRole($role);

        return $user;
    }
}

应用程序/库/ UserRepository.php

<?php

namespace App\Repositories;

use App\Contracts\RoleRepositoryInterface as RoleRepository;
use App\Contracts\UserRepositoryInterface;
use App\Models\User;

class UserRepository extends User implements UserRepositoryInterface
{

    /**
     * @var RoleRepository
     */
    private $roleRepo;

    /**
     * Class constructor
     *
     * @param RoleRepository $roleRepo
     */
    public function __construct(RoleRepository $roleRepo)
    {
        $this->roleRepo = $roleRepo;
    }

    /**
     * Create new or update an existing user
     *
     * @param  array  $data
     * @param  int    $id
     *
     * @return bool|int|static
     */
    public function store(array $data, $id = null)
    {
        if (is_null($id)) {
            $user = $this->create($data);
            $userWithRole = $this->roleRepo->attachRole($user, $data['role']);

            return $user;
        } else {
            return $this->where('id', $id)
              ->update($data);
        }
    }
}

非常感谢任何答案......

1 个答案:

答案 0 :(得分:1)

我认为您的代码中存在错误,特别是RepositoryServiceProvider。它应该是:

foreach ($models as $model) {
        $this->app->bind(
            "App\Contracts\\{$model}RepositoryInterface",
            "App\Repositories\\{$model}Repository"
        );
}

注意:错误在连接中,您得到"App\Contracts\\{$model}Interface",但它应该是"App\Contracts\\{$model}RepositoryInterface"