假设我有两个实现契约的存储库(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"
]
}
config/app.php
'providers' => [
/*
* Laravel Framework Service Providers...
*/
...
/**
* Third-party Service Providers
*/
...
/*
* Application Service Providers...
*/
...
/**
* Custom Service Providers...
*/
App'Providers'RepositoryServiceProvider::class,
app/Provider/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"
);
}
}
}
app/Controllers/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);
}
app/Compacts/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);
}
app/Compacts/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);
}
app/Repositories/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;
}
}
app/Repositories/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);
}
}
}
任何答案都将不胜感激。。。
我认为您的代码中有一个错误,特别是在RepositoryServiceProvider
中。应该是:
foreach ($models as $model) {
$this->app->bind(
"App'Contracts''{$model}RepositoryInterface",
"App'Repositories''{$model}Repository"
);
}
注意:错误在串联中,您得到了"App'Contracts''{$model}Interface"
,但它应该是"App'Contracts''{$model}RepositoryInterface"