Edit: rephrased the question
If you call a method on a facade class, will an actual object of that class be instantiated for calling that method, or will an object of that class be instantiated during bootstrapping the application and that same object will be returned every time (like a singleton)?
I understand that normal to the container bound classes will be instantiated when App::make('class name') is done, but since you don't have to manually use App::make I don't understand where the object or instance of the class "lives"?
BTW I understand that facades in laravel aren't the same thing as the design pattern.
I think Dayle Rees explains it best:
Each Facade is linked to an instance of a component in the container. The static methods of a Facade are shortcuts, and when called, they call the appropriate public method of the object that they represent within the container
So, when a method like
Cache::get('key');
is called, it is actually resolved in the IoC container to
$app->make('cache')->get('key');
Now that instance of Cache is within $app, or the main Container.
Edit: All classes are registered, not necessarily instantiated during the bootstrapping of Laravel.
Related
In the service container of Laravel, I can bind both singleton and instance. From the Laravel doc:
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'));
});
Binding Instances
You may also bind an existing object instance into the container using the instance method. The given instance will always be returned on subsequent calls into the container:
$api = new HelpSpot\API(new HttpClient);
$this->app->instance('HelpSpot\API', $api);
Q1) So what is the difference between the two concepts? Can I guess that for singleton binding, Laravel upon first request builds the object itself through internal service container mechanism and then supplies it on subsequent calls whereas in the case of instance binding, service container is explicitly given an already built object which it supplies on every request?
Or is there any other explanation?
Q2) Why do we need both binding options?
Difference between singleton and instance
The two concepts are very much alike. The only difference is, indeed, the fact that you either pass in a class/interface or an object.
Singleton docs:
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
Instance docs
You may also bind an existing object instance into the container using the instance method. The given instance will always be returned on subsequent calls into the container
Why do we need both?
The answer to this question is probably rooted in the Laravel philosophy. From what I see in most of the features Laravel provides, there's more than one way to solve an issue. It feels like this is one of those as well. There's slight differences which might make singleton or instance usage preferable in some cases.
Singleton usage
The use of singleton will help keep your application light, as these classes/interfaces do not get created if they are not used.
Instance usage
In some cases you might've already created an object, which you still need to inject into other places. That's where instances comes in.
Additional to what #PtrTon said, the difference is also in the time, the instance is created. Using an instance, the instance is—of course— created before passing to the service container, meaning it's created quite early. Whereas using a singleton, the instance is created the first time, the binding is resolved as far as I know which can be a considerable amount of time after the example where you pass an instance.
I like to spend time studying how frameworks are coded in attempt to better my code.
As far as I know the Scope Resolution Operator in PHP calls a function in a class as a static function, meaning that you do not have access to '$this' because the class hasn't been instantiated.
But when I started reading up how the Laravel 4 Auth works I noticed that the documentation tells you to use Auth::check() or Auth::user() to retrieve information, yet the code in those functions is using many '$this' statements.
Can anyone explain to me how they are able to retrieve the instance properties if the functions are being called as static methods?
Here is the link to the github raw file for Laravel Auth
https://raw.githubusercontent.com/illuminate/auth/master/Guard.php
Laravel uses a development pattern known as Facades and Inversion of Control (IoC) in order to take static calls to some objects (the 'Facade') and retrieve an actual instance of an object (from the IoC container) to call the method on.
Put another way, when you do Auth::check() and Auth::user() those seemingly static calls get replaced with actual object instances from within the IoC container, so Auth::check() becomes $auth->check() with $auth being derived from within the container.
This allows you to 1) Write Auth::check() instead of $auth = new Auth; $auth->check() and 2) let the IoC container do all of the dirty work around actually creating the instance you want, so if implementation details change later you don't have to rewrite any code that uses the Auth class.
See this documentation page about facades and this question about IoC in general for more information.
As a side note, the Auth facade referred to in Auth::check() et al is actually this class: https://github.com/laravel/framework/blob/master/src/Illuminate/Support/Facades/Auth.php
It's a Fcade.
When you're calling Auth::{anything}, you're actually calling Illuminate\Support\Facades\Auth. The static method is only used as an entry point.
This is a simplified version of the Facade design pattern:
http://sourcemaking.com/design_patterns/facade/php
My understanding:
A dependency is when an instance of ClassA requires an instance of ClassB to instantiate a new instance of ClassA.
A dependency injection is when ClassA is passed an instance of ClassB, either through a parameter in ClassA's constructor or through a set~DependencyNameHere~(~DependencyNameHere~ $param) function. (This is one of the areas I'm not completely certain on).
An IoC container is a singleton Class(can only have 1 instance instantiated at any given time) where the specific way of instantiating objects of those class for this project can be registered. Here's a link to an example of what I'm trying to describe along with the class definition for the IoC container I've been using
So at this point is where I start trying use the IoC container for more complicated scenarios. As of now it seems in order to use the IoC container, I am limited to a has-a relationship for pretty much any class I want to create that has dependencies it wants to define in the IoC container. What if I want to create a class that inherits a class, but only if the parent class has been created in a specific way it was registered in the IoC container.
So for example: I want to create a child class of mysqli, but I want to register this class in the IoC container to only instantiate with the parent class constructed in a way I've previously registered in the IoC container. I cannot think of a way to do this without duplicating code (and since this is a learning project I'm trying to keep it as 'pure' as possible). Here are some more examples of what I am trying to describe.
So here are some of my questions:
Is what I'm trying to do above possible without breaking some principle of OOP? I know in c++ I could use dynamic memory and a copy constructor to accomplish it, but I haven't been able to find that sort of functionality in php. (I will admit that I have very little experience using any of the other magic methods besides __construct, but from reading and __clone if I understood correctly, I couldn't use in the constructor it to make the child class being instantiated a clone of an instance of the parent class).
Where should all my dependency class definitions go in relation to the IoC? (Should my IoC.php just have a bunch of require_once('dependencyClassDefinition.php') at the top? My gut reaction is that there is a better way, but I haven't come up with one yet)
What file should I be registering my objects in? Currently doing all the calls to IoC::register() in the IoC.php file after the class definition.
Do I need to register a dependency in the IoC before I register a class that needs that dependency? Since I'm not invoking the anonymous function until I actually instantiate an object registered in the IoC, I'm guessing not, but its still a concern.
Is there anything else I'm overlooking that I should be doing or using? I'm trying to take it one step at a time, but I also don't want to know that my code will be reusable and, most importantly, that somebody who knows nothing about my project can read it and understand it.
Put simply (because it's not a problem limited to OOP world only), a dependency is a situation where component A needs (depends on) component B to do the stuff it's supposed to do. The word is also used to describe the depended-on component in this scenario. To put this in OOP/PHP terms, consider the following example with the obligatory car analogy:
class Car {
public function start() {
$engine = new Engine();
$engine->vroom();
}
}
Car depends on Engine. Engine is Car's dependency. This piece of code is pretty bad though, because:
the dependency is implicit; you don't know it's there until you inspect the Car's code
the classes are tightly coupled; you can't substitute the Engine with MockEngine for testing purposes or TurboEngine that extends the original one without modifying the Car.
It looks kind of silly for a car to be able to build an engine for itself, doesn't it?
Dependency injection is a way of solving all these problems by making the fact that Car needs Engine explicit and explicitly providing it with one:
class Car {
protected $engine;
public function __construct(Engine $engine) {
$this->engine = $engine;
}
public function start() {
$this->engine->vroom();
}
}
$engine = new SuperDuperTurboEnginePlus(); // a subclass of Engine
$car = new Car($engine);
The above is an example of constructor injection, in which the dependency (the depended-on object) is provided to the dependent (consumer) through the class constructor. Another way would be exposing a setEngine method in the Car class and using it to inject an instance of Engine. This is known as setter injection and is useful mostly for dependencies that are supposed to be swapped at run-time.
Any non-trivial project consists of a bunch of interdependent components and it gets easy to lose track on what gets injected where pretty quickly. A dependency injection container is an object that knows how to instantiate and configure other objects, knows what their relationship with other objects in the project are and does the dependency injection for you. This lets you centralize the management of all your project's (inter)dependencies and, more importantly, makes it possible to change/mock one or more of them without having to edit a bunch of places in your code.
Let's ditch the car analogy and look at what OP's trying to achieve as an example. Let's say we have a Database object depending on mysqli object. Let's say we want to use a really primitive dependency indection container class DIC that exposes two methods: register($name, $callback) to register a way of creating an object under the given name and resolve($name) to get the object from that name. Our container setup would look something like this:
$dic = new DIC();
$dic->register('mysqli', function() {
return new mysqli('somehost','username','password');
});
$dic->register('database', function() use($dic) {
return new Database($dic->resolve('mysqli'));
});
Notice we're telling our container to grab an instance of mysqli from itself to assemble an instance of Database. Then to get a Database instance with its dependency automatically injected, we would simply:
$database = $dic->resolve('database');
That's the gist of it. A somewhat more sophisticated but still relatively simple and easy to grasp PHP DI/IoC container is Pimple. Check its documentation for more examples.
Regarding OP's code and questions:
Don't use static class or a singleton for your container (or for anything else for that matter); they're both evil. Check out Pimple instead.
Decide whether you want your mysqliWrapper class extend mysql or depend on it.
By calling IoC from within mysqliWrapper you're swapping one dependency for another. Your objects shouldn't be aware of or use the container; otherwise it's not DIC anymore it's Service Locator (anti)pattern.
You don't need to require a class file before registering it in the container since you don't know if you're going to use an object of that class at all. Do all your container setup in one place. If you don't use an autoloader, you can require inside the anonymous function you register with the container.
Additional resources:
Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler
Don't look for things -- a Clean Code Talk about IoC/DI
I have a class I call my Dispatcher and when its dispatch() method is run it instantiates the requested controller.
My AbstractController has a constructor like
public function __construct(RequestInterface $request, ResponseInterface $response, ViewFactory $viewFactory, ServiceFactory $serviceFactory)
As you can see my controllers have 4 dependencies.
At the moment when I instantiate my Dispatcher I inject the ViewFactory and ServiceFactory into its constructor and then when I run the dispatch() method I supply the Request and Response objects as arguments and I can then inject all four dependencies into my controller.
Would it be better to just supply all the controllers dependencies when calling the dispatch() method or supply them all in the constructor of the Dispatcher and then run a dispatch() method with no arguments or is there a better way overall?
You have 4 dependencies you want to inject in a new controller instance, 2 have a request/response life cycle and 2 have a longer life cycle (process?), before invoking some method on it. I would separate the creation of the controller from the invoking by creating a controller factory.
The controller factory would instantiate a controller using a method that receives only the request and reponse objects as parameters. The factory would be aware of the life cycle of the two longer lifed dependencies, perhaps share the same life cycle. The factory's user is then free to invoke any method they would like on the (abstract) controller returned. This is more flexible than the delegation pattern you propose. You could of course still use delegation, but then I would probably still have the Dispatcher only do dispatching and leave object creation to a factory.
Of course, there is no right answer with these kind of questions. It all depends on a lot of factors (requirements, size of codebase, the project, etc). Hope this helps though. Good luck!
Some "blah"
Here is a rule of thumb that I use when design API: if your class has 3+ dependencies, it is doing too much.
The dependencies that you pass in the constructor, should be mandatory for your instance to function. In your case, you have a controller there. Controllers repsonsibilities are as follows:
A controller can send commands to its associated view to change the view's presentation of the model. It can also send commands to the model to update the model's state.
source: wikipedia
Controllers should not be responsible for creation or rendering of the view instance.
Regarding the original question:
I am not sure what is the role of the Dispatcher instances, but they should not be dealing with creation logic itself. What you essentially end up with here is a mix of possible LoD violation and a definite SRP violation.
The creation logic should be segregate to factories and builders. This way would also let you decouple your Dispatcher instances from the footprint of controller's constructor. Currently, if you introduced a different subclass of controllers, with different set of dependencies, you would also need to change the Dispatcher implementation.
As for "how to make a factory", you can find a simplified example here.
I've been using the DI concept for some time now, but now I'm starting to use a dependency injection container (DIC). Although one thing isn't clear for me.
In my DIC I keep (for example) a Config object and Request object. I understand that these objects in a request scope (The same instance is used each time you request it from this container) remain the same. But this only happens when I re-use the same instance of the DIC.
How should I pass the DIC arround my classes? Say that I want to use it in my Router class, do I need to pass it in the constructor of my Router class? But the Router class is created in another class, and that one should also already have this DIC object.
Or should I create a singleton of this DIC?
Don't go the Singleton route. It effectively takes all the advantages the DIC gives you. Usually you pass the container in constructor, or as a method parameter where applicable.
Yes, this requires you to put an extra effort in passing the container object around your application, but as a result your code reflects well that these classes are dependent on this object to work.