Laravel - difference between singleton and instance binding in service container - php

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.

Related

Intercepting function calls referenced via $this in unit tests

The Scenario
I'm writing unit tests to test an API which is currently in development stages. I have a mock container class (decorator pattern), which contains an array of mocks which will be executed in place of calls to the actual objects.
These mock containers are placed in a DI container during a test run and calls hit the container instead of the model/controllers. In most cases, we allow controllers functions through, but we occasionally want to mock them. The mock container operates by catching inaccessible function calls via __call and either returning assigned mock data or hitting the inner object.
The Problem
This works fine in the usage case of:
$this->c['Controller_Name']->functionHere()
As c['Controller_Name'] is an instance of our mock container, but the problem with this approach comes from a Controller referencing itself via $this->functionHere() when functionHere should be mocked, but the call occurs on $this which is the instance of a Controller and not our Mock Container.
Is there a plausible method for intercepting the calls to a classes own members, so I can catch $this->functionHere() and translate it appropriately into $this->c['Controller_Name']->functionHere()
Without knowing your setup its hard to talk specifics but as you are using Dependency Injection then ensuring that you interface any implementations you wish to exclude from testing will mean that you can create mock versions, mapped using a separate TestDIModule for example. That way you don't need to intercept anything.
As for catching function calls within an object - I would suggest that if you are needing to do this it may indicate that your class is performing multiple "units" of work thus could be refactored into separate classes and interface them. Extracting these out to interfaces, as described above, would allow these to be mocked and tested independently.

Laravel Facades: Are underlying classes instantiated?

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.

How to keep an instance of a Dependency Injection Container (PHP)

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.

How to access my singletons without using global state?

I know that Singleton pattern is bad because it uses global state. But in most applications, you need to have a single instance of a class, like a database connection.
So I designed my Database object without using the singleton pattern but I instanciate it only once.
My question is, how can I access my object in the low level classes (deep in the object graph) without passing it all over the place?
Let's say I have an application controller which instanciates (ask a factory to instanciate it actually) a page controller which instaciates a User model which requires the database object.
Neither my app controller nor my page controller need to know about the database object but the User class does. How am I suppose to pass the object to it?
Thanks for your time!
Consider using a global container:
You register the objects that are indeed relevant to the several subsystems of the application.
You then request that container those objects.
This approach is very popular in dependency injection frameworks (see Symfony DI, Yadif).
Singleton is bad, no doubt about it.
In the case you describe, the database object is an implementation detail of the User object. The layers above need only know about the User, not the database object.
This becomes much more apparent if you hide the user object behind an interface and only consume that interface from the layers above.
So the page controller should deal only with the interface, not the concrete class that depends on the database object, but how does in create new instances? It uses an injected Abstract Factory to create instances of the interface. It can deal with any implementation of that interface, not only the one that relies on a database object.
Once more, you hide the page controller behind an interface. This means that the concrete implementation's reliance on the Abstract Factory becomes another implementation detail. The Application Controller only consumes the page controller interface.
You can keep wrapping objects like that like without ever needing to pass around instances. Only in the Composition Root do you need to wire all dependencies together.
See here for a related answer with examples in C#: Is it better to create a singleton to access unity container or pass it through the application?
The way I've always accomplished this is to implement a static getInstance function that will return a reference to the single instance of that class. As long as you make sure that the only way you access the object is through that method, you can still ensure that you only have one instance of the singleton. For example:
class deeply_nested_class {
public function some_function() {
$singleton = Singleton::getInstance();
}
}
There are two main objects involved in loading/saving a user using the database: the user and the repository.
You seem to have implemented the functionality on the User, but I think it belongs on the Repository. You should pass the user to the Repository to save it.
But, how do you get hold of the Repository? This is created once at the top level and passed into services that need it.
The construction dependency graph and the call dependency graph are not the same thing.
Given the example you outlined, you are almost there. You are already using a factory to instantiate your page controller, but your page controller is instantiating the users directly and as your User needs to know the database.
What you want to do is use a factory to instantiate your User objects. That way the factory can know about the database and can create User instances which know about it too. You will probably be better off making interfaces for all the dependencies, which will help with testing and will mean your code is nicely decoupled.
Create an IUserFactory which creates IUser implementations and pass this into your PageControllerFactory, then your ApplicationController only needs to know about the PageControllerFactory, it doesn't need to know anything about the IUserFactory or the database.
Then in your application start up you can create all of your dependencies and inject them in to each other through the constructors.

Accessing the DI container

I'm starting a new project and setting up the base to work on. A few questions have risen and I'll probably be asking quite a few in here, hopefully I'll find some answers.
First step is to handle dependencies for objects. I've decided to go with the dependency injection design pattern, to which I'm somewhat new, to handle all of this for the application.
When actually coding it I came across a problem. If a class has multiple dependencies and you want to pass on multiple dependencies via the constructor (so that they cannot be changed after you instantiate the object).
How do you do it without passing an array of dependencies, using call_user_func_array(), eval() or Reflection? This is what i'm looking for:
<?php
class DI
{
public function getClass($classname)
{
if(!$this->pool[$classname]) {
# Load dependencies
$deps = $this->loadDependencies($classname);
# Here is where the magic should happen
$instance = new $classname($dep1, $dep2, $dep3);
# Add to pool
$this->pool[$classname] = $instance;
return $instance;
} else {
return $this->pool[$classname];
}
}
}
Again, I would like to avoid the most costly methods to call the class. Any other suggestions?
Also, how do I access the DI class inside classes, for example, in controllers that need to access different models? Should I call it statically or pass it along each class that would require it? I don't think the last idea is feasible.
Thanks everyone.
[Before I start, let me say that I'm mostly a Java programmer - with only a little bit of PHP knowledge. But I'll simply try to get the most important concepts across without language specifics.]
Dependency Injection is based on two parts of code:
Construction
Execution
In its most extreme shape, there are no new operators to be found in the Execution part. All of them are moved into the Construction part. (In practice, this will be toned down.)
All of the construction happens - in the Construction part. It creates the graph of objects needed for Execution bottom up. So let's assume, it should construct A:
A depends on B, and
B depends on C.
Then
C is constructed first.
Then B is constructed with C as a parameter.
Then A is constructed with B as a parameter.
So C doesn't have to be passed as a constructor parameter to A. This small example doesn't illustrate strongly enough, how much this reduces the amount of objects that have to be passed around to quite a small number.
The Dependency Injector itself should not be passed into the Execution part. This is one of the basic mistakes everyone (including myself) tries to make, when they first come in contact with DI. The problem is, that this would completely blur the lines between Construction and Execution. Another way to say it is, that it would violate the Law of Demeter. Or in pattern speak: It would eventually "degrade" the Dependency Injection pattern to the Service Locator pattern. It's debatable, if this is really a degradation, but in any case it's usually not a good idea to misuse the Dependency Injector as a Service Locator.
So whenever you need to give one of your constructed objects the capability to produce other objects during execution, instead of passing the Dependency Injector, you would only pass simple Providers (a term used by the Java DI framework Guice). These are rather simple classes that can only create a certain kind of object. They have similarities with a factory.
First try to pass the required dependencies directly to the constructor.
So, to sum it up:
Build objects bottom-up.
Only pass as few dependencies as required to create an object.
Once your done, start executing.
During execution, you can still fetch newly created objects by using Providers.
But don't take it too far: Simple objects can still be created without a Provider :-)
And now, all you'll have to do is to translate this stuff into quality code. Maybe others can help you out with a few PHP examples.
Addendum: A little bit more about Providers
As noted above, the notion "Provider" (a specialized factory) is a bit specific to the Java DI framework Guice. This framework can automatically create a Provider for any type of object. However, the concept is generally useful for DI. The only difference is, that without the help of Guice or a similar framework, you'll have to write the Providers yourself - but that's quite easy:
Let's say, B depends on C.
If B just needs one fixed instance of C, then you don't need a Provider - you can simply construct B with the constructor argument C.
If B needs to create more instances of C during execution, then just write a class called CProvider with a get() method, that can create a new instance of C. Then pass an instance of CProvider into the constructor of B, and store the Provider in an instance field of B. Now B can call cProvider.get() when it needs a new instance of C.
Providers are part of the Construction code, so you're allowed to use new C(...)! On the other hand, they're not part of the Execution code, so you shouldn't have any execution logic there.
CProvider can be passed into multiple constructors of course. You can also write multiple versions CProvider1, CProvider2, ... - where each can construct different versions of C objects with different properties. Or you simple instantiate CProvider multiple times with different arguments.
You should look into using an IOC container to manage your dependencies for you. A good IOC container should take care of passing dependencies between dependent contructors for you.
There is an existing question asking about IOC container options for PHP.
It looks like you are trying to roll your own dependency injection container. Why not use one that already exists, like Symfony, Crafty or Sphicy?

Categories