私はこの質問が何度も聞かれたことを知っていますが、どの回答も私を助けませんでした。
Laravel 5で例外が発生しています
BindingResolutionException in Container.php line 785:
Target [App\Contracts\CustomModelInterface] is not instantiable.
私が成功せずにやったこと:
App\Providers\AppRepositoryProvider
プロバイダーにapp.php
を登録しますphp artisan clear-compiled
構造:
app
- Contracts
- CustomModelInterface.php
- Models
- CustomModel.php
- Repositories
- CustomModelRepository.php
- Providers
- AppRepositoryProvider.php
- Services
- MyService.php
App\Contracts\CustomModelInterface.php
<?php namespace App\Contracts;
interface CustomModelInterface {
public function get();
}
App\Repositories\CustomModelRepository.php
<?php namespace App\Repositories;
use App\Contracts\CustomModelInterface;
use App\Models\CustomModel;
class CustomModelRepository implements CustomModelInterface {
private $Model;
public function __construct(CustomModel $model) {
$this->Model = $model;
}
public function get() {
return 'result';
}
}
App\Services\MyService.php(ビジネスロジック/コントローラーとリポジトリの間のレイヤーを保持)
<?php namespace App\Services;
use App\Contracts\CustomModelInterface;
class MyService {
private $Model;
public function __construct(CustomModelInterface $customModel) {
$this->Model= $customModel;
}
public function getAll() {
return $this->Model->get();
}
}
App\Providers\AppRepositoryProvider.php
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppRepositoryProvider extends ServiceProvider {
public function boot() {}
public function register() {
$models = array(
'CustomModel'
);
foreach ($models as $idx => $model) {
$this->app->bind("App\Contracts\{$model}Interface", "App\Repositories\{$model}Repository");
}
}
}
私のコントローラーは次のようになります。
<?php namespace App\Http\Controllers;
use App\Services\MyService;
class SuperController extends Controller {
private $My;
public function __construct(MyService $myService) {
$this->My = $myService;
}
public function getDetails() {
return $this->My->getAll();
}
}
composer.json
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"App\\Models\\": "app/Models/",
"App\\Contracts\\": "app/Contracts/",
"App\\Repositories\\": "app/Repositories/"
}
},
みなさん、ありがとうございますが、問題は私のAppRepositoryProviderにありました。バインディング例外なので、明らかに問題はバインディングにありました:)
正しいファイル:
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppRepositoryProvider extends ServiceProvider {
public function boot() {}
public function register() {
$models = array(
'CustomModel',
'CustomModel2',
'CustomModel3'
);
foreach ($models as $model) {
$this->app->bind("App\Contracts\\{$model}Interface", "App\Repositories\\{$model}Repository");
}
}
}
"App\Contracts\\{$model}Interface"
(「{」記号をエスケープしない)を使用しており、App\Contracts\CustomModelInterface
(予期しないエスケープ)の代わりに正しい文字列App\Contracts\{$model}Interface
を生成していることに注意してください。
新しいリポジトリ/契約のペアを作成するたびに、次のことを確認します。
無駄なデバッグに何時間も費やしたため、この短いチェックリストにたどり着きました。
私にとっては、app->providers->RepositoryServiceProvider
でregisterメソッドでこのようなリポジトリをバインドするのを忘れていました
public function register()
{
$this->app->bind(
\App\Play\Contracts\PatientRepository::class,
\App\Play\Modules\PatientModule::class
);
}
RepositoryServiceProvide
rがAppServiceProvider
に登録されていることを確認してください。
public function register()
{
$this->app->register(RepositoryServiceProvider::class);
}
私はこのエラーを実行し過ぎました:
php artisan config:clear
php artisan clear-compiled
php artisan optimize
php artisan config:cache
関連する:
App\Services\MyService.php
では、インスタンス化しようとする依存性注入でそのインターフェイスを渡します-
public function __construct(CustomModelInterface $customModel) {
$this->Model= $customModel;
}
それは間違っています。
そのクラスにそれを実装してみてください-class MyService implements CustomModelInterface {
とそのインターフェースの機能を使用してください-
$this->get();
または、それを使用しています-class CustomModelRepository implements CustomModelInterface {
もしそうなら-
public function __construct(CustomModelRepository $customModel) {
$this->Model= $customModel;
}
その後、インターフェイスメソッドにアクセスすることもできます。
これに似た問題が発生したばかりで、エラーの原因は、サービスプロバイダークラスで$defer
をtrue
に設定したが、必要なprovides()
メソッドを実装していなかったことです。
クラスの作成を熱心にロードするのではなく、必要になるまで延期した場合は、プロバイダーが提供するクラスの配列を返すだけのprovides
メソッドも実装する必要があります。インターフェイスの場合、具体的なクラスではなく、インターフェイスの名前である必要があります。
例えば。
public method provides(): array
{
return [
MyInterface::class,
];
}
現在のドキュメント: https://laravel.com/docs/5.5/providers#deferred-providers
これが他の人の助けになることを願っています。
みんな心配しないで。あなたの問題の解決策があります。
私はあなたのための例を持っています。
ステップ1:php artisan make:repository Repository/Post //このコマンドを追加することで、リポジトリと雄弁なファイルを作成できます
ステップ2:そのファイルを追加した後、使用するコントローラーでこのリポジトリを追加/使用する必要があります。
例:se App\Repositories\Contracts\PostRepository;
ステップ3:アプリを実行する場合、コントローラーにそのレポを追加した後、「インターフェースはインスタンス化できません」などのエラーが表示されます。リポジトリを作成してコントローラーで使用したためですが、laravelは、このリポジトリがどこに登録され、どの雄弁にバインドされているかを知りません。そのため、エラーがスローされます。
ステップ4:このエラーを解決するには、レポジトリをAppServiceProviderの雄弁家にバインドする必要があります。例えば:
AppServiceProvider.phpファイル
<?php
namespace App\Providers;
// **Make sure that your repo file path and eloquent path must be correct.**
use App\Repositories\Contracts\PostRepository; // **Use your repository here**
use App\Repositories\Eloquent\EloquentPostRepository; **// Use your eloquent here**
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider {
/**
* Register any application services.
*
* @return void
*/
public function register() {
**// And bind your repository and eloquent here. **
$this->app->bind(PostRepository::class, EloquentPostRepository::class);
}
}
ステップ5:レポと雄弁をバインドした後、コントローラーでレポのすべての方法を使用できます。楽しい.....
質問がある場合はお知らせください。
最後に行うことは、リポジトリにバインドしたインターフェイスを使用することです。
それを設定し、laravelアプリを実行して、エラーが発生しないことを確認してください。
私の場合、リポジトリとインターフェイスが一致していません。
interface UserRepositoryInterface{
public function get($userId);
}
class UserRepository implements UserRepositoryInterface{
public function get(int $userId);
}
ご覧のとおり、インターフェイスのgetメソッドにはタイプヒントは含まれていませんが、UserRepositoryクラスのgetメソッドにはタイプヒントがあります。
インターフェイスバインディングの使用をすぐに開始した場合、このエラーは発生しません。
ここでの問題は、Laravelがインターフェイスのインスタンスを作成しようとするので、App\Contracts\CustomModelInterface
を何にもバインドしないことだと思います。
App\Providers\AppRepositoryProvider.php
には次のものしかありません:
$models = array(
'Model'
);
ただし、この配列にはCustomModel
も含める必要があるため、次のようになります。
$models = array(
'Model',
'CustomModel',
);
これは、プライベートとして宣言されているクラスの_constructor、またはブロックされていることによっても発生する可能性があることに注意してください...コンストラクタを呼び出せない場合、バインディングは失敗します