在存储库中注入
Injection in Repository
我发现了很多关于我的问题的问题,并尝试了(我认为)所有的解决方案,但我无法解决问题。我可能忽略了一些非常容易的事情。
我正在使用 Laravel 5。我尝试实现一个存储库模式。
我有一个 Eloquent 模型“\Notos\Kind”。
然后我有这个界面:
namespace Notos\Contracts;
interface Kind
{
public function findByName($name);
}
我的存储库如下所示:
namespace Notos\Repository;
use Illuminate\Database\Eloquent\Model;
use Notos\Contracts\Kind as KindContract;
class Kind implements KindContract
{
protected $kind;
public function __construct(Model $kind)
{
$this->kind = $kind;
}
public function findByName($name)
{
return $this->kind->firstOrCreate(array('name' => $name));
}
}
我的服务提供商:
namespace Notos\Providers;
use Illuminate\Support\ServiceProvider;
use Notos\Kind;
use Notos\Repository\Kind as KindRepository;
class RepoServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->bind('Notos\Contracts\Kind', function ($app) {
return new KindRepository(new Kind);
});
}
}
我使用存储库的控制器:
namespace Notos\Http\Controllers;
use Notos\Repository\Kind as KindRepository;
class KindController extends Controller
{
protected $kind;
public function __construct(KindRepository $kind)
{
$this->kind = $kind;
}
public function find($name)
{
return $this->kind->findByName($name);
}
}
此提供商已在 config/app 中注册。php
当我尝试执行 KindController@find 时出现此错误:
BindingResolutionException in Container.php line 785:
Target [Illuminate\Database\Eloquent\Model] is not instantiable.
我找不到我做错了什么。
如果我将 __construct(Model $kind) 更改为 __construct(Kind $kind),它会完美运行。
有什么想法吗?
谢谢
首先,我建议您将函数添加到 class 名称中,例如,而不是 Kind
用于存储库使用 KindRepository
,合同也是如此。否则你将有 3 种 classes(当然在不同的命名空间中)但是很难分析代码。
这里的问题是,在您的 KindController
中,您尝试直接注入 KindRepository
,但在构造函数中您使用 Model
。它不会起作用,因为 Model
只是抽象的 class。你应该怎么做才能让它发挥作用?
代码中:
$this->app->bind('Notos\Contracts\Kind', function ($app) {
return new KindRepository(new Kind);
});
你告诉 Laravel 当你使用 Notos\Contracts\Kind
时,它应该在构造函数中使用 Kind
为你创建 KindRepository
- 你看你在这里说的是合同,而不是关于存储库本身。
所以要让它工作,你应该在你的控制器中使用你的合同而不是你的存储库。
代替行:
use Notos\Repository\Kind as KindRepository;
你应该写:
use Notos\Contracts\Kind as KindRepository;
现在应该可以使用了。
我发现了很多关于我的问题的问题,并尝试了(我认为)所有的解决方案,但我无法解决问题。我可能忽略了一些非常容易的事情。
我正在使用 Laravel 5。我尝试实现一个存储库模式。 我有一个 Eloquent 模型“\Notos\Kind”。
然后我有这个界面:
namespace Notos\Contracts;
interface Kind
{
public function findByName($name);
}
我的存储库如下所示:
namespace Notos\Repository;
use Illuminate\Database\Eloquent\Model;
use Notos\Contracts\Kind as KindContract;
class Kind implements KindContract
{
protected $kind;
public function __construct(Model $kind)
{
$this->kind = $kind;
}
public function findByName($name)
{
return $this->kind->firstOrCreate(array('name' => $name));
}
}
我的服务提供商:
namespace Notos\Providers;
use Illuminate\Support\ServiceProvider;
use Notos\Kind;
use Notos\Repository\Kind as KindRepository;
class RepoServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->bind('Notos\Contracts\Kind', function ($app) {
return new KindRepository(new Kind);
});
}
}
我使用存储库的控制器:
namespace Notos\Http\Controllers;
use Notos\Repository\Kind as KindRepository;
class KindController extends Controller
{
protected $kind;
public function __construct(KindRepository $kind)
{
$this->kind = $kind;
}
public function find($name)
{
return $this->kind->findByName($name);
}
}
此提供商已在 config/app 中注册。php
当我尝试执行 KindController@find 时出现此错误:
BindingResolutionException in Container.php line 785:
Target [Illuminate\Database\Eloquent\Model] is not instantiable.
我找不到我做错了什么。 如果我将 __construct(Model $kind) 更改为 __construct(Kind $kind),它会完美运行。
有什么想法吗? 谢谢
首先,我建议您将函数添加到 class 名称中,例如,而不是 Kind
用于存储库使用 KindRepository
,合同也是如此。否则你将有 3 种 classes(当然在不同的命名空间中)但是很难分析代码。
这里的问题是,在您的 KindController
中,您尝试直接注入 KindRepository
,但在构造函数中您使用 Model
。它不会起作用,因为 Model
只是抽象的 class。你应该怎么做才能让它发挥作用?
代码中:
$this->app->bind('Notos\Contracts\Kind', function ($app) {
return new KindRepository(new Kind);
});
你告诉 Laravel 当你使用 Notos\Contracts\Kind
时,它应该在构造函数中使用 Kind
为你创建 KindRepository
- 你看你在这里说的是合同,而不是关于存储库本身。
所以要让它工作,你应该在你的控制器中使用你的合同而不是你的存储库。
代替行:
use Notos\Repository\Kind as KindRepository;
你应该写:
use Notos\Contracts\Kind as KindRepository;
现在应该可以使用了。