In my laravel project I have following interface, repository and controller.
This is Interface
interface TrainingClassTypeInterfaces
{
public function updateTrainingClassType($id, $request);
}
This is Repository
use App\Models\Trainings\AppTrainingClassType;
class TrainingClassTypeEloquent implements TrainingClassTypeInterfaces
{
protected $model;
public function __construct(AppTrainingClassType $appTrainingClassType)
{
$this->model = $appTrainingClassType;
}
public function updateTrainingClassType($id, $request)
{
$response = false;
$isUpdated = $this->model::where('training_class_id',$id)->update([
'app_id' => $request->app_id
]);
....
}
}
This is controller
class TrainingClassTypesController extends \TCG\Voyager\Http\Controllers\VoyagerBaseController
{
protected $trainingService;
public function __construct(TrainingClassTypeEloquent $trainingClassTypeInterfaces) {
$this->trainingService = $trainingClassTypeInterfaces;
}
public function insertOrUpdate()
{
...
$this->trainingService->updateTrainingClassType($id, $request);
..
}
}
Everything working fine till here
As you can see I am using TrainingClassTypeEloquent's method inside TrainingClassTypesController
. But it was returning error something like
Argument 1 passed to...::__construct() must be an instance of
Basically it was asking me to put instance of Model into TrainingClassTypeEloquent
class. Then I did as following
$TCTypes = new AppTrainingClassType();
$TCT = new TrainingClassTypeEloquent($TCTypes);
$TCT->updateTrainingClassType($id, $request);
which was working fine but I was confused that this approach is not proper, there should be some proper way.
After googling I found another solution which is singleton binding, and then I tried following in AppServiceProvider
$this->app->singleton(
\App\Services\Voyager\Eloquent\TrainingClassType\TrainingClassTypeInterfaces::class,
\App\Services\Voyager\Eloquent\TrainingClassType\TrainingClassTypeEloquent::class
);
After adding this singleton binding, I notice script was working without providing model instance into TrainingClassTypeEloquent
class.
I would like to know how $this->app->singleton()
is working, so in this way my concept would be clear about it. If someone knows then kindly guide me about it.
Thank you so much
It is all about BINDING a service to the service container .
What does $this->app->singleton();
method do?
The singleton method binds a class or interface into the service container so that Laravel can maintain dependency (when using an interface as the constructor parameter).
(Actually Singleton is a design pattern. Singleton implementation always returns the same object on subsequent calls instead of a new instance). So $this->app->singleton();
method returns the same object again and again.
Point to be noted that Laravel doc says:
There is no need to bind classes into the container if they do not depend on any interfaces . The container does not need to be instructed on how to build these objects, since it can automatically resolve these objects using reflection.
But your controller class depends on an interface, so the container needs to be informed and to do this, you need to use this $this->app->singleton();
method but there are other ways around.
Again, at the same time, this TrainingClassTypeEloquent::class
has a dependency of AppTrainingClassType::class
. But in this case, we do not need to worry about that because Laravel uses Reflection API to maintain its dependency as this class does not use interface as like TrainingClassTypesController::class
class.
Once you are done with binding the service to the container, Laravel will then automagically put the service onto the constructor method as an argument where the interface is used.
I hope this would help you. You may find more help from this answer .
You need to register TrainingClassTypeEloquent
$this->app->singleton(TrainingClassTypeInterfaces::class, static function ($app) {
return new TrainingClassTypeEloquent(new AppTrainingClassType());
});
Then you can inject it in your Controller
public function insertOrUpdate(TrainingClassTypeInterfaces $trainingService, $id)
{
$trainingService->updateTrainingClassType($id, request());
}
Binding A Singleton
The singleton
method binds a class or interface into the container that should only be resolved one time. Once a singleton binding is resolved, the same object instance will be returned on subsequent calls into the container:
$this->app->singleton('HelpSpot\API', function ($app) {
return new \HelpSpot\API($app->make('HttpClient'));
});
For more go to HERE
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.