Dependency Injection - php

I have this code
Controller
<?php
namespace App\Exchange\Helpers;
use App\Contracts\Exchange\Notification;
class Locker
{
protected $notification;
public function __construct(Notification $notification)
{
$this->notification = $notification;
}
public function index()
{
return $this->notification->sendMessage('test');
}
Interface
<?php
namespace App\Contracts\Exchange;
interface Notification
{
public function sendMessage($message);
}
File Kernel.php
namespace App\Providers;
use App\Contracts\Exchange\Notification;
use App\Exchange\Helpers\Notification\Telegram;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
$this->app->bind(Notification::class, function (){
return new Telegram(env('TELEGRAM_EXCHANGE_TOKEN'), env('TELEGRAM_EXCHANGE_CHAT_ID'));
});
}
If I try to use new Locker(); I get a TypeError error: Too few arguments to function App\Exchange\Helpers\Locker::__construct(), 0 passed in Psy Shell code on line 1 and exactly 1 expected

Your controller should extend Illuminate\Routing\Controller in order for dependency injection to work. Or just refactor your __construct method using app helper:
<?php
namespace App\Exchange\Helpers;
use App\Contracts\Exchange\Notification;
class Locker
{
protected $notification;
public function __construct()
{
$this->notification = app(Notification::class);
}
public function index()
{
return $this->notification->sendMessage('test');
}
}

Related

BindingResolutionException and Target is not instantiable

Error:
BindingResolutionException in Container.php line 887:
Target [App\Helpers\Contracts\AccessTokenInterface] is not instantiable.
Route:
Route::get('/', 'LoginController#handleProviderCallback');
Controller:
namespace App\Http\Controllers;
use App\Helpers\Contracts\AccessTokenInterface;
class LoginController extends Controller
{
public function handleProviderCallback(AccessTokenInterface $accessTokenInstance)
{
return $accessTokenInstance->getSomething();
}
}
Provider:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Helpers\Contracts\AccessTokenInterface;
use AccessToken;
class TokenServiceProvider extends ServiceProvider
{
protected $defer = true;
public function boot()
{
//
}
public function register()
{
$this->app->bind(AccessTokenInterface::class, function(){
return new AccessToken();
});
}
}
Helper:
namespace App\Helpers;
use App\Helpers\Contracts\AccessTokenInterface;
class AccessToken implements AccessTokenInterface
{
protected $something;
public function setSomething()
{
$something = 100;
}
public function __construct()
{
$this->setSomething();
}
public function getSomething(){
return $something;
}
Interface:
namespace App\Helpers\Contracts;
Interface AccessTokenInterface
{
public function getSomething();
public function setSomething();
}
I have registered Provider in providers and AccessToken in aliases for Helper.
I have read some stackoverflow answers but can't find solution. I am new to this.
Where I am going wrong?
Write in your config/app.php
'providers' => [
...
App\Providers\TokenServiceProvider::class,
...
]
Hope it help you :)

BindingResolutionException and Target is not instantiable

Error:
BindingResolutionException in Container.php line 887:
Target [App\Helpers\Contracts\AccessTokenInterface] is not instantiable.
Route:
Route::get('/', 'LoginController#handleProviderCallback');
Controller:
namespace App\Http\Controllers;
use App\Helpers\Contracts\AccessTokenInterface;
class LoginController extends Controller
{
public function handleProviderCallback(AccessTokenInterface $accessTokenInstance)
{
return $accessTokenInstance->getSomething();
}
}
Provider:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Helpers\Contracts\AccessTokenInterface;
use AccessToken;
class TokenServiceProvider extends ServiceProvider
{
protected $defer = true;
public function boot()
{
//
}
public function register()
{
$this->app->bind('AccessTokenInterface::class', function(){
return new AccessToken();
});
}
}
Helper:
namespace App\Helpers;
use App\Helpers\Contracts\AccessTokenInterface;
class AccessToken implements AccessTokenInterface
{
protected $something;
public function setSomething()
{
$something = 100;
}
public function __construct()
{
$this->setSomething();
}
public function getSomething(){
return $something;
}
Interface:
namespace App\Helpers\Contracts;
Interface AccessTokenInterface
{
public function getSomething();
public function setSomething();
}
I have registered Provider in providers and AccessToken in aliases for Helper.
I have read some stackoverflow answers but can't find solution. I am new to this.
Where I am going wrong?
Remove the quotes from the bind method in your provider:
$this->app->bind(AccessTokenInterface::class, function(){
return new AccessToken();
});

Laravel view share doesnt work in modularing system

simply i can use modular system in laravel, but i cant use view share in this solution,
app/Http/Controllers/Controller.php
abstract class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function __construct()
{
view()->share('name', 'MY NAME');
}
}
app/Modules/NewCurrency/Controllers/IndexController.php
class IndexController extends Controller
{
public function __construct()
{
parent::__construct();
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return view('layouts.admin.new_user.index');
}
}
resources/views/layouts/admin.new_user.index.blade.php
{{ $name }}
I get this Error:
Undefined variable: name
Did you check this
View::share()
Because the method that you wrote is used by other way. You should place calls to share within a service provider's boot method.
<?php
namespace App\Providers;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
view()->share('key', 'value');
}
public function register()
{
//
}
}

Laravel 5 repository injection

I'm quite new in Laravel 5, what I am trying to do is a simple repository with dependency injection. But I'm stuck with this error:
Argument 1 passed to
App\Http\Controllers\Api\UserController::__construct() must implement
interface App\Repositories\UserInterface, instance of
App\Repositories\UserRepository given
Here is my code:
UserController:
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Response;
use App;
use Auth;
use Crypt;
use Lang;
use Image;
use Storage;
use Config;
use Validator;
use App\User;
use App\Repositories\UserInterface;
class UserController extends Controller
{
protected $config;
protected $users;
public function __construct(UserInterface $users)
{
$this->middleware('api');
$this->middleware('auth', ['except' => 'getInfo']);
$this->users = $users;
$this->config = Config::get('images.avatar');
}
UserInterface:
namespace App\Repositories;
use App\Repositories\BaseInterface;
interface UserInterface extends BaseInterface
{
};
BaseInterface:
namespace App\Repositories;
interface BaseInterface
{
public function all();
public function paginate($count);
public function find($id);
}
BaseRepository
namespace App\Repositories;
use App\Repositories\BaseInterface;
class BaseRepository implements BaseInterface
{
protected $model;
public function __call($name, $args)
{
// $this->getNewInstance()->{$name($args)};
return call_user_func_array([
$this->getNewInstance(),
$method], $args);
}
public function all($relations = [])
{
$instance = $this->getNewInstance();
return $instance->with($relations)->all();
}
public function find($id, $relations = [])
{
$instance = $this->getNewInstance();
return $instance->with($relations)->find($id);
}
public function findOrFail($id, $relations = [])
{
$instance = $this->getNewInstance();
return $instance->with($relations)->findOrFail($id);
}
public function paginate($count)
{
}
protected function getNewInstance()
{
return new $this->model;
}
}
UserRepository
namespace App\Repositories;
use App\Repositories\BaseRepository;
Class UserRepository extends BaseRepository
{
protected $model = 'App\User';
}
RepositoryServiceProvider
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App;
class RepositoryServiceProvider extends ServiceProvider
{
/**
* Register any error handlers.
*
* #return void
*/
public function boot()
{
}
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
//
App::bind('App\Repositories\UserInterface', 'App\Repositories\UserRepository');
}
}
Of course RepositoryServiceProvider is added under service providers in my config/app.php
Please help, I'm almost sure that I've tried everything whatever I found in Google.
Your UserRepository has to implement UserInterface:
namespace App\Repositories;
use App\Repositories\BaseRepository;
class UserRepository extends BaseRepository implements UserInterface
// ^^^^^^^^^^^^^^^^^^^^^^^^
{
protected $model = 'App\User';
}

Repositories Not be Instantiated

I'm trying to find out why I'm receiving this error. I'm following along. However the only difference is that at the time of the recording it was done with Laravel 4.25 and I am now using Laravel 5.0.
Repositories and Inheritance
BindingResolutionException in Container.php line 785:
Target [App\Repositories\User\UserRepository] is not instantiable.
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Repositories\User\UserRepository;
use Illuminate\Http\Request;
class UsersController extends Controller {
private $userRepository;
public function __construct(UserRepository $userRepository) {
$this->userRepository = $userRepository;
}
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index() {
$users = $this->userRepository->getAll();
return $users;
}
}
<?php
namespace App\Repositories\User;
use App\Repositories\EloquentRepository;
class EloquentUserRepository extends EloquentRepository implements UserRepository
{
private $model;
function __construct(User $model) {
$this->model = $model;
}
}
<?php
namespace App\Repositories\User;
interface UserRepository {
public function getAll();
}
<?php
namespace App\Repositories;
abstract class EloquentRepository {
public function getAll() {
return $this->model->all();
}
public function getById() {
return $this->model->findOrFail($id);
}
}
You are type hinting an interface, and not the class itself. This error is occurring because Laravel cannot bind an interface because the binding must be instantiable. Abstract classes or interfaces are not valid unless Laravel knows the concrete (instantiable) class to substitute in for the abstract class / interface.
You will need to bind the EloquentUserRepository to the interface:
App::bind('UserRepository', 'EloquentUserRepository');

Categories