ERROR:Target [RepositoryInterface] is not instantiable while building [Errorファイル名]

Target [RepositoryInterface] is not instantiable while building [Errorファイル名]

こんなエラーに遭遇しました。
Controllerで__constractに引数としてInterfaceを記載しインスタンス化しようとした時のことです。

原因はproviderの記載ミス

app/Providers/RepositoryServiceProvider.php

まずは正解のコードを記載します。

$this->app->bind(
    'App\Repositories\Document\DocumentRepositoryInterface',
    'App\Repositories\Document\DocumentRepository',
);
$this->app->bind(
    'App\Repositories\Document\DocumentCollectionRepositoryInterface',
    'App\Repositories\Document\DocumentCollectionRepository',
);
これを下のように間違えた記載をしていたことがエラーの原因でした。
$this->app->bind(
    'App\Repositories\Document\DocumentRepositoryInterface',
    'App\Repositories\Document\DocumentRepository',
    'App\Repositories\Document\DocumentCollectionRepositoryInterface',
    'App\Repositories\Document\DocumentCollectionRepository',
);

Application::bindはふたつ以上のペアを渡せない

RepositoryInterfaceとRepositoryの組み合わせを登録するメソッドなのに間違えたコードではbindの中に4つも入ってます。

Application::bind は、第一引数の文字列をキーにして第二引数のクラス(のインスタンス)を値にするためのメソッドなので、ふたつ以上のペアを一度に渡すことはできないのです。

インタフェースごとに bind を呼ぶ

つまりはこのルールを無視したからエラーになったわけですね。

▼ 解決情報 参考元

https://qiita.com/antk/items/38971fba1de4e6872b82

まとめ

「そもそもインスタンス化ってなんでする?」という疑問ありますよね。私もそう思ってました。
「ServiceでModelを呼び出せば良いのに、なぜRepositoryに書き出すのか」とか「Repositoryをstaticで作って呼び出せばインスタンス化する必要ないじゃん」とか。

それらの疑問については、下記参考サイトを一読することをお勧めします。

【Laravel】引数でタイプヒントしただけでインスタンスがもらえるのはなぜ?Laravelの魔法を解明してみる。 #初心者 - Qiita

はじめに Laravelを使ってアプリケーションを実装するうえで、 最も便利だと感じる機能が、「コンストラクターインジェクション」です。 Laravel 6.x コントローラ:コン…

世界一わかりやすくクラスとインスタンスを説明する #Swift - Qiita

はじめに クラスやインスタンスの説明は、世に多くありますが、たいてい難しい単語並びすぎて、初学者にはとっかかりにくいと感じます。 本記事は、具体例を多く入れて、…

以下はコードを書いていて思った私的な感想ですがメモしておきます。
現在の開発はチームで行うことが多いと思います。
その際、人のコードを見ることももちろんあります。
コンストラクタインジェクションを行なっていると、コードの前段でどんなClassを利用しているかがとても明確になります。
そのため、解析する時間が圧倒的に短くなりますし、細かくClass分けをしていると(書くときは面倒臭いですが)修正箇所を探し出す時間が短縮できます。
時間と共にコードの中身なんて忘れますからね。
面倒ですが、便利です。

\ 最新情報をチェック /

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください。