Dependency Injection in Laravel 5 Package To Use or Not To Use - laravel

I am developing a package for Laravel 5, I decided to benefit from dependency injection in my package when using the Core classes of Laravel, but after reading more and also having asked this question
Best approach for Dependency Injection in Laravel 5 package
Now I came up with the idea that if we are using Facades so much and calling static methods like FaceadeName:nameOfMethod the Container actually creates an object for us and calls its method, so to some extend using dependency injection for laravel for classes which are also available through the Facades are is almost useless.
For example having this class:
class MyController extends \App\Http\Controllers\Controller
{
public $text;
public $lang;
public function __construct()
{
// Some codes here
}
public function myFunction(){
$this->text = \Lang::get('package::all.text1');
}
}
doing this:
App::bind('lang', function($app)
{
return new \Lang();
});
and then in the function:
public function myFunction()
{
$lang = \App::make('lang');
$this->text = $lang::get('package::all.text1');
}
is almost useless because we bind something to container that is already bound there
It is not a great idea to change the myFunction to
public function myFunction(\Lang $lang){
$this->text = $lang::get('package::all.text1');
}
as well, it might look like method injection but it doesn't bring so much advantages. Therefore it would be better not to use dependency injection for Facades in Laravel.
Please let me know if I am right or not and please argue my opinion with the right answer if I am wrong.

Facades provide a way of accessing the container through a class, so when you're accessing \Lang::function() you're actually calling app('translator')->function(). So in you're above example when you're binding the Lang facade into the container, you've then bound it twice, which isn't quite what you want.
All Laravel's functionality is already bound into the container and can be accessed by calling app('object'). You can see all the bindings here http://laravel.com/docs/5.0/facades
For dependency injection, you shouldn't be trying to inject the facades, but rather the classes the facades are already referencing. So for example, the \Lang facade references Illuminate\Translation\Translator which is bound to the container as translator
In your classes you can do the following
use App\Http\Controllers\Controller;
use Illuminate\Translation\Translator;
class MyController extends Controller
{
protected $translator;
// Dependency injection example
public function __construct(Translator $translator)
{
$this->translator = $translator;
}
public function index()
{
$text = $this->translator->get('package::all.text1');
}
// Method injection example
public function myFunction(Translator $translator)
{
$text = $translator->get('package::all.text1');
}
}

Related

Laravel dependency injection without relying on the controller

I'm trying to figure out how to inject a dependency into a class in Laravel.
My structure:
SimpleController extends BaseController
{
public function example(SimpleModel $model, SimpleValidationRequest $request)
{
$result = $model->doStuff()
return $this->makeResponse($result);
}
}
SimpleModel extends Model
{
public function doStuff(ComplexService $service)
{
$service->doComplexLogic($this);
}
}
I have registered the ComplexService in my own service provider:
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(ComplexService::class);
}
}
I want to inject the service straight into the simpleModel's doStuff method, without having to inject it into the controller and then into the model. We're busy moving a monolithic application to Laravel and have service classes that contain all the complex business logic. Much of the logic is shared between different classes, so a controller method might call a model that calls a service that ends up making 4 or 5 calls to other services, and I want to be able to inject another service into any method that needs it without having to send it down from the controller all the way through to the bottom method that might need it.
Is there a way to do this? I have been looking online but everything I've found has required me to inject the service into the controller and then sending it through the application from there, which I want to avoid.
You can simply call the singleton inside the method via the app() helper
SimpleModel extends Model
{
public function doStuff(ComplexService $service)
{
app()->singleton(ComplexService::class)->doComplexLogic($this);
}
}
or recover the singleton by injecting it in the model via it's __construct() method.

Issue in creating REST Service using laravel

We are trying to develop an Android app that required a REST API to show data from web server.
We tried to use Laravel resource to create REST service like below:
Route::resource('list', 'ListController');
namespace App\Http\Controllers;
use mymodel
class ListController extends Controller
{
public function getShow($id)
{
$Jsondata=list($id);
return $JsonData;
}
}
But it's not working as expected need some token key or some other authentication and authorization need to know how to set.
We should utilize the Repository / Gateway design pattern:
For example, when dealing with the User model, first create a User Repository. The only responsibility of the user repository is to communicate with the database (performing CRUD operations). This User Repository extends a common base repository and implements an interface containing all methods we require:
class EloquentUserRepository extends BaseRepository implements UserRepository
{
public function __construct(User $user) {
$this->user = $user;
}
public function all() {
return $this->user->all();
}
public function get($id){}
public function create(array $data){}
public function update(array $data){}
public function delete($id){}
// Any other methods we need go here (getRecent, deleteWhere, etc) }
Then, create a service provider, which binds your user repository interface to your eloquent user repository. Whenever you require the user repository (by resolving it through the IoC container or injecting the dependency in the constructor), Laravel automatically gives you an instance of the Eloquent user repository you just created. This is so that, if you change ORMs to something other than eloquent, you can simply change this service provider and no other changes to your codebase are required:
use Illuminate\Support\ServiceProvider;
class RepositoryServiceProvider extends ServiceProvider {
public function register() {
$this->app->bind(
'lib\Repositories\UserRepository', // Assuming you used these
'lib\Repositories\EloquentUserRepository' // namespaces
);
}}
Next, create a User Gateway, who's purpose is to talk to any number of repositories and perform any business logic of your application:
use lib\Repositories\UserRepository;
class UserGateway {
protected $userRepository;
public function __construct(UserRepository $userRepository) {
$this->userRepository = $userRepository;
}
public function createUser(array $input)
{
// perform any sort of validation first
return $this->userRepository->create($input);
}}
Finally, create our User web controller. This controller talks to our User Gateway:
class UserController extends BaseController
{
public function __construct(UserGatway $userGateway)
{
$this->userGateway = $userGateway;
}
public function create()
{
$user = $this->userGateway->createUser(Input::all());
}}
By structuring the design of your application in this way, you get several benefits: you achieve a very clear separation of concerns, since your application will be adhering to the Single Responsibility Principle (by separating your business logic from your database logic) . This enables you to perform unit and integration testing in a much easier manner, makes your controllers as slim as possible, as well as allowing you to easily swap out Eloquent for any other database if you desire in the future.
For example, if changing from Eloquent to Mongo, the only things you need to change are the service provider binding as well as creating a MongoUserRepository which implements the UserRepository interface. This is because the repository is the only thing talking to your database - it has no knowledge of anything else. Therefore, the new MongoUserRepository might look something like:
class MongoUserRepository extends BaseRepository implements UserRepository
{
public function __construct(MongoUser $user) {
$this->user = $user;
}
public function all() {
// Retrieve all users from the mongo db
}}
And the service provider will now bind the UserRepository interface to the new MongoUserRepository:
$this->app->bind(
'lib\Repositories\UserRepository',
'lib\Repositories\MongoUserRepository'
);
Throughout all your gateways you have been referencing the UserRepository, so by making this change you're essentially telling Laravel to use the new MongoUserRepository instead of the older Eloquent one. No other changes are required.
Number one is that what is not working? if you mean that the response is not showing then its because your function actually doesn't even seem to be going any where, and number two are you new to Laravel?
Okay if this is what you have:
namespace App\Http\Controllers;
use mymodel;
class ListController extends Controller
{
public function getShow($id)
{
$Jsondata=list($id); return $JsonData;
}
}
Then I can be safe to say a lot of things is wrong.
To my understanding using Route::resource('list', 'ListController'); in your routes file creates show, edit, update and destroy paths, and also expects to see these functions too (I have not proven this to the core though) but thats my understanding.
so you can simply start laravel life by doing having your routes with
Route::get('list', 'ListController#show')
Then change your ListController to something like this:
namespace App\Http\Controllers;
use mymodel;
class ListController extends Controller
{
public function show($id)
{
$jsonData= ['my' => 'json data'];
return $jsonData;
}
}
If this works for you, then cool else so many thing might already be wrong with your setup.
Note: you might need to take your time to learn to use laravel from the documentation page. If API is your interest then try DIngo api. Also try to learn to use markup :)
Hope this helps :)

What is Laravel IoC Container in simple words?

Can anyone explain dependency injection and IoC container in simple and easy words as i am beginner to laravel. thanks
The answer became longer than I wanted it to be in the first place. I included a bit of background information. Still if you're looking for short term explanations, read the first paragraph of the IoC-Container and the bold passages.
Dependency Injection
Dependency Injection is a design pattern, that does what the name states. It injects objects into the constructor or methods of other objects, so that one object depends on one or more other objects.
<?php
class DatabaseWriter {
protected $db;
public function __construct(DatabaseAdapter $db)
{
$this->db = $db;
}
public function write()
{
$this->db->query('...');
}
}
You can see that we require the classes constructor a DatabaseAdapter instance to be passed. Since we are doing that in the constructor, an object of that class cannot be instantiated without it: We are injecting a dependency. Now, that we know that the DatabaseAdapter is always existent within the class we can easily rely on it.
The write() method just calls methods on the adapter, since we definitely know it exists because we made use of DI.
The enormous advantage of using DI instead of misusing static classes, god objects, and other stuff like that is, that you can easily track down where the dependencies come from.
The other huge advantage is, that you can easily swap out dependencies. If you want to use another implementation of your dependency just pass it to the constructor. You don't need to hunt down hardcoded instances anymore in order to be able to swap them.
Leaving aside the fact that by using Dependency Injection you will easily be able to Unit-Test your classes, since you can just mock the dependencies which is hardly possible with hardcoded dependencies.
The three types of Dependency Injection
Constructor Injection
The type of Dependency Injection explained above is called Constructor Injection. That simply means that dependencies are passed as arguments to the classes constructor. The dependencies are then stored as properties and thus made available in all methods of the class. The big advantage here is, that a object of the class cannot exist without passing the dependencies.
Setter Injection
This type makes use of dedicated methods to inject dependencies. Instead of using the constructor. The advantage of using Setter Injection is, that you can add dependencies to an object after it has been created. It's commonly used for optional dependencies. Setter Injection is also great to declutter your constructor and have your dependencies only in methods where you need them.
<?php
class RegisterUserService {
protected $logger;
public function setLogger( Logger $logger )
{
$this->logger = $logger;
}
public function registerUser()
{
// Do stuff to register the user
if($this->logger)
$this->logger->log("User has been registered");
}
}
$service = new RegisterUserService;
$service->registerUser(); // Nothing is Logged
$service->setLogger(new ConcreteLogger);
$service->registerUser(); // Now we log
The object can be instantiated without any dependencies. There is a method to inject the dependency (setLogger()) which can be called optionally. Now it's up to the methods implementation to either make use of the dependency or not (if it's not set).
It's worth pointing out to be cautious with Setter Injection. Calling methods or accessing attributes on a dependency that has not yet been injected will result in a nasty Fatal error: Call to a member function XXX() on a non-object . Therefore everytime the dependency is accessed it has to be null-checked first. A much cleaner way to go about this would be to use the Null Object Pattern and to move the dependency into the constructor (as optional argument, if nothing is passed the null object is created inside the class)
Interface Injection
The idea of interface injection is basically, that the method(s) to inject a dependency is defined in an interface. The class that is going to need the dependency must implement the interface. Hereby it is ensured that the needed dependency can be properly injected into the dependent object. It's a stricter form of the previously explained Setter Injection.
<?php
interface Database {
public function query();
}
interface InjectDatabaseAccess {
// The user of this interface MUST provide
// a concrete of Database through this method
public function injectDatabase( Database $db );
}
class MySQL implements Database {
public function query($args)
{
// Execute Query
}
}
class DbDoer implements InjectDatabaseAccess {
protected $db;
public function injectDatabase( Database $db )
{
$this->db = $db;
}
public function doSomethingInDb($args)
{
$this->db->query();
}
}
$user = new DbDoer();
$user->injectDatabase( new MySQL );
$user->doSomethingInDb($stuff);
The meaningfulness of Interface Injection is open to dispute. Personally I have never used it. I prefer Constructor Injection over it. That allows me to accomplish the exact same task without the need of additional interfaces on the injectors side.
Dependency Inversion
Instead of depending on a concrete instance we can also depend on abstractions.
<?php
class DatabaseWriter {
protected $db;
public function __construct(DatabaseAdapterInterface $db)
{
$this->db = $db;
}
public function write()
{
$this->db->query('...');
}
}
Now we inverted the control. Instead of relying on a concrete instance, we can now inject any instance that consumes the type hinted interface. The interface takes care that the later concrete instance implements all the methods that we are going to use, so that we can still rely on them in the dependent classes.
Make sure you get that one, because it is a core concept of the IoC-Container.
The IoC Container
In the shortest terms I can think of I would describe the IoC container like that:
The IoC-Container is a component that knows how instances are created and knows of all their underlying dependencies and how to resolve them.
If we take our example above, imagine that the DatabaseAdapter itself has it's own dependencies.
class ConcreteDatabaseAdapter implements DatabaseAdapterInterface{
protected $driver;
public function __construct(DatabaseDriverInterface $driver)
{
$this->driver = $driver;
}
}
So in order to be able to use the DatabaseAdapter you would need to pass in a instance of the DatabaseDriverInterface abstraction as a dependency.
But your DatabaseWriter class does not know about it, nor should it. The DatabaseWriter should not care about how the DatabaseAdapter works, it should only care about that a DatabaseAdapter is passed and not how it needs to be created. That's where the IoC-Container comes in handy.
App::bind('DatabaseWriter', function(){
return new DatabaseWriter(
new ConcreteDatabaseAdapter(new ConcreteDatabaseDriver)
);
});
As I already said, the DatabaseWriter itself does not know anything about the dependencies of it's dependencies. But the IoC-Container knows all about them and also knows where to find them. So eventually when the DatabaseWriter class is going to be instantiated, the IoC-Container first is asked how it needs to be instantiated. That's what the IoC-Container does.
Simply spoken (if you are into design patterns). It's a bit of a combination of a Dependency Injection Container (which I already explained above) and a Service Locator.
consider you have a Car class like bellow :
class Car
{
protected $wheels;
protected $engine;
public function __construct()
{
$this->engine = new Engine('BMW Engine');
$this->wheels = array(
new Wheel('some Wheel Brand'),
new Wheel('some Wheel Brand'),
new Wheel('some Wheel Brand'),
new Wheel('some Wheel Brand')
);
}
public function go()
{
//do fun stuff here
}
}
now think about reusing your code and for example you want to have another car class which is for Toyota company.
you should write exactly above code with just a little editing as below :
class AnotherCar
{
protected $wheels;
protected $engine;
public function __construct()
{
$this->engine = new Engine('Toyota Engine');
$this->wheels = array(new Wheel('some Wheel Brand'),
new Wheel('some Wheel Brand'),
new Wheel('some Wheel Brand'),
new Wheel('some Wheel Brand'));
}
public function go()
{
//do fun stuff here
}
}
your code will grow and grow and will be a pain if you don't use DI(Dependency Injection) or IoC(Inversion Of Control).
lets talk about what are the above code problems :
1- its not reusable .
2- it doesn't care about performance (Volume of code in your Ram , ...)
3- your code grows and you will not understand it yourself after a time .
...
so lets use DI and solve the problem
class Car
{
protected $wheels;
protected $engine;
public function __construct($myWheels , $myEngine)
{
$this->engine = $myEngine;
$this->wheels = $myWheels;
}
public function go()
{
//do fun stuff here
}
}
now easily you can create every car object with above Car class like below :
$BMW = new Car (new Engine('BMW' , array(new Wheel('wheel beand') ,new Wheel('wheel beand') ,new Wheel('wheel beand') ,new Wheel('wheel beand') )));
see !
much easier ! also your code is much readable and reusable !
lets consider you have a big project that have so many classes that probably lot of objects and classes depends on other objects and classes.
it will bother you to keep in mind while working that which class depends on what classes and ...
this is where IOC comes in and solve the problems.
IOC pattern or maybe solution is not really easy to understand you should face to problems I mentioned earlier .
IOC just is neede in big projects !
in java Spring is one of the most famous IOC container
and what IOC does???
it contains lots of config file ( or some IOC container configs are in source code and also some of them have user interface to configs)
and this configs contain relation between class and which class for loading depend on which classes
this also is a big help for lazy loading !
just when you need to load an object you load its dependecies !

Laravel 4 Inversion of Control

I'm watching a video explaining the basics of laravel's IoC container, and I'm having trouble understanding what this code is doing. Specifically, I don't understand the parameter in the constructor function of the UserRepository class. I haven't had much luck finding an example of this syntax on the php site.
http://vimeo.com/53009943
<?php
class UserRepository {
protected $something;
public function __construct(Something $something)
{
$this->something = $something;
}
}
class Something {}
?>
Quoting Laravel's documentation:
There are two ways the IoC container can resolve dependencies: via
Closure callbacks or automatic resolution.
But first, what is a dependency? In the code that you have posted, the UserRepository class has one dependency, which is the Something class. It means that UserRepository is going to depend on Something somewhere in its code. Instead of using it directly, by doing something like this
$something = new Something;
$something->doSomethingElse();
it is being injected in its constructor function. This technique is known as dependency injection. So, these code snippets would do the same, without and with dependency injection.
// Without DI
class UserRepository {
public function doSomething()
{
$something = new Something();
return $something->doSomethingElse();
}
}
Now, using DI, which would be the same as you posted:
// With DI
class UserRepository {
public function __construct(Something $something)
{
$this->something = $something;
}
public function doSomething()
{
return $this->something->doSomethingElse();
}
}
You are saying that you don't understand the parameter being passed in the constructor __constructor(Something $something). That line is telling PHP that the constructor expects one parameter, $something, which must be an instance of the Something class. This is known as type hinting. Passing a parameter which is not an instance of Something (or any subclass), will throw an exception.
Finally, let's go back to the IoC container. We've said before that its function is to resolve dependencies, and it can do it in two ways.
First one, Closure callbacks:
// This is telling Laravel that whenever we do
// App::make('user.repository'), it must return whatever
// we are returning in this function
App::bind('UserRepository', function($app)
{
return new UserRepository(new Something);
});
Second one, automatic resolution
class UserRepository {
protected $something;
public function __construct(Something $something)
{
$this->something = $something;
}
}
// Now when we do this
// Laravel will be smart enough to create the constructor
// parameter for you, in this case, a new Something instance
$userRepo = App::make('UserRepository');
This is specially helpful and allows your classes to be more flexible, when using interfaces as parameters for your constructors.

Symfony 2: Dependency injection (DI) of Controllers

Is there any chance to make Controllers dependent on their services not via using of service container inside them but through pure constructor dependency injection?
I would like to write controllers in this way:
<?php
class ArticleController extends \Symfony\Bundle\FrameworkBundle\Controller\Controller
{
private $articleFacade;
private $articleRepository;
public function __construct(ArticleFacade $articleFacade, ArticleRepository $articleRepository)
{
$this->articleFacade = $articleFacade;
$this->articleRepository = $articleRepository;
}
public function indexAction()
{
...
}
}
Unfortunatelly as I can see Symfony ControllerResolver does new instances of Controllers not via ServiceContainer but via simple return new $controller call.
Absolutely in fact it's recommended and if you look at most 3rd party bundles such as FOSUser you can see that that is exactly what they do.
The trick is to define your controllers as services and then use the service id instead of the class name.
http://symfony.com/doc/current/cookbook/controller/service.html
Keep in mind that you will have to inject all your needed services such as entity managers and you won't usually extend the symfony base class. Of course you could inject the complete container but that tends to be frowned on.

Resources