The Laravel docs indicate that the appropriate way to bind a singleton is with the App::singleton() method, but internally Laravel will use the bindShared() method (for example, in TranslationServiceProvider).
I assume that the documented approach is preferred, but is there a functional difference? If not, is there any reason for having two approaches (beyond maybe historical accident)?
I've been wondering the same thing. I don't know the motivations behind this, but I can speak to a few differences.
Here is the definition of the two methods from Laravel 4.2:
public function singleton($abstract, $concrete = null)
{
$this->bind($abstract, $concrete, true);
}
public function bindShared($abstract, Closure $closure)
{
$this->bind($abstract, $this->share($closure), true);
}
Similarities:
Both methods call bind() under the hood.
Both methods pass true to the 3rd parameter of bind(), which signifies that this is a shared object.
In both cases, because this is a shared object, a call to isShared($abstract) will return true.
In both cases, because this is a shared object, a call to make($abstract) will return only the first instance.
Differences:
singleton() will accept a Closure or a string. bindShared() will only accept a Closure, not a string.
bindShared(), in addition to binding the object into the IOC container as a shared object, takes the additional step of wrapping the passed Closure in a share'd Closure, which prevents the passed Closure from being executed more than once. At first glance, this appears to be a double assurance that the object will be treated as a singleton. I can only guess why this might be desirable.
bindShared() is called 87 times inside the framework. singleton() is called 0 times.
They are (were) functionally identical, except that bindShared() only accepts closures.
Thus bindShared() has been deprecated in Laravel 5.1 (PR 9009 - commit 829060f) and removed in Laravel 5.2 (PR 9037).
Case finally solved :)
bind($abstract, $concrete, $shared)
Adds $abstract as a key to the container, with $concrete being the concrete class to instantiate in its place. Mainly used for providing a concrete implementation for an interface.
share($closure)
Given a closure (only), makes it act as if it was shared (instance/singleton style), and returns it. Technically equivalent to App::bind($key, $closure, true) but goes about it a different way. Mainly used in service providers to add a fully resolvable service to the IoC container.
bindShared($abstract, $closure)
A shortcut that was introduced in 4.1 that caters to a common pattern. Essentially helps those who want to bind a shared instance in the container. See below for example.
singleton($abstract, $concrete)
Simply an alias to bind with the $shared argument set to true. Mainly used for providing a concrete implementation for an interface, but one that should only have one instance (database connection, etc.)."
This is from http://alexrussell.me.uk/laravel-cheat-sheet/ I think this link should be helpfull
I think mainly for backwards compatibility. Singleton explains better behavior than bindShared. Removing bindShared would mean Package developers to refactor their code.
Related
I have read in laravel's facade documentation the following sentence:
Typically, it would not be possible to mock or stub a truly static
class method.
1) question 1: I'm trying to understand facade in laravel. As I guess, it's implemented because if we have classes, and they have big namespaces and big names and every time we want to use this class and we don't want to use new keyword and use statements, we use the facade which is an easier code and readable. I also think that laravel implemented facades because they wanted to write non-static functions in their classes so that they could be tested. After all of this, we use facades like static classes (because of readability and not using new and use), but in reality, it makes new instances.
Am I right?
2) If the above is right, can you provide me an example why it's not possible to test a static method as laravel docs said?
A facade does not solve the big namespaces problem you mentioned. Big namespaces are solved using aliases. You can declare them in your config/app.php and internally Laravel will use class_alias when you call them. This is how e.g. \Cache or \DB work.
A facade is basically a proxy class to a singleton object instance of another class (the facade itself ensures the instance is a singleton).
Typically to register a singleton in Laravel you:
Add app()->singleton(ABC::class) in your service provider
Access it via app()->make(ABC::class)->...
A facade basically takes care of that for you if you haven't already registered that class as a singleton.
Basically a facade is a way to proxy that singleton instance of another class.
Also it's generally not possible to mock or stub static methods however if you are using facades you can do \ABCFacade::swap($mockObject) and therefore your facades can be mocked.
It is also false that you cannot test a static method. You can absolutely test a static method. For example:
public testStaticMethod() {
$this->assertEquals(1, ABC::method()); // We tested a static method against a desired behaviour
}
What you usually can't do is mock a static method. Here's how you would typically mock something with PHPUnit:
public testWithDependency() {
$dependency = $this->getMockBuilder(Dependency::class)->getMock();
$dependency->expects($this->once())->method('dependantMethod')->willReturn(true);
$objectToTest = new ABC($dependency); //We're passing a fake dependency which behaves in an ideal way
$this->assertEquals(1, $objectToTest->methodToTest()); //Any calls to the dependency will call mock methods and not real ones
}
The problem arises when trying to mock a static method. As you can see mocking creates mock instances of a certain type. It can't mock the static members of that type because the mock object itself is not actually of that type.
However as I just found out the statement that it's not possible to mock or stub a static method is not entirely true. There's the AspectMock you can mock static methods or helper methods. This seems to work by intercepting all function calls via a custom autoloader.
This being said, just because you can doesn't mean it's good practice to use static methods, there's other issues to consider like e.g. you normally can't have static interfaces in most programming languages or you normally can't override static methods in most programming languages. Note the "in most programming languages" part here. In PHP it's entirely possible to override static methods with late static binding but that means you need to make a conscious decision about this when implementing the static method.
Another disadvantage is that a class of statics can't implement an interface because interfaces apply to object behaviours and not the static behaviour. Therefore you can't swap out one interface for another if you are using statics which is a major disadvantage.
In general the aversion to static methods is not because of testability but because if you are coding in OOP you are really limited if you are using statics.
Hopefully this will help clear up some confusion.
I'm looking at Laravel's service container docs, specifically the binding section.
What are the differences and when should I use each type of binding? The documentation mentions:
Simple Binding
Singleton Binding
Instance Binding
Primitive binding
Interface binding
First, let's see what it actually is:
IoC container is a component that knows how instances are created. It also knows of all their underlying dependencies and how to resolve them.
Container's knowledge about instance creation and dependency resolving might be guided by the programmer. That's why Laravel's container provides various binding APIs for me, and you.
"Resolving out of the container" is a phrase you read/hear a lot. It means that you tell the container to make something for you based on the [optional] guidance you gave her previously.
Before you continue reading about bindings, I strongly recommend you to read this answer:
What is Laravel IoC Container in simple words?
Simple Binding
app()->bind(DatabaseWriter::class, function ($app) {
return new DatabaseWriter(
$app->make(DatabaseAdapterInterface)
);
});
You say to the container that when you want to resolve an instance of DatabaseWriter class, follow this logic I just told you in the closure coz I know better. Every single time that you want to resolve the class, you must follow this and deliver me a new instance.
You use this type of bindings all the time. You're giving the container small recipes on how to make your things for you.
Singleton Binding
Same as simple bindings, with one obvious difference. You're telling the container that I want only one instance of this class across my whole application. The first time you're resolving the class, follow the logic in the closure I passed to you, but be sure that you just return that only instance every other time you want to resolve it. Deliver me the only instance you were allowed to make.
It's a singleton, right? Once a singleton binding is resolved, the same object instance will be returned on subsequent calls into the container.
Obviously, you use this type of binding when you want to utilize the Singleton pattern. It's rare these days.
Instance Binding
It's like doing a favor for the container. You don't tell her how to instantiate a certain class, you do it yourself and just give her the instance. She holds it for you and returns it on subsequent calls into the container.
It's especially handy when you're unit-testing. If you bind a mock instance to the container for some class, all the subsequent calls to app()->make() will return that mock for you. So you're practically injecting a class mock all over the app when the actual class is used.
class QuestionsControllerTest extends TestCase
{
public function testQuestionListing()
{
$questionMock = Mockery::mock('Question')
->shouldReceive('latest')
->once()
->getMock();
// You're telling the container that everytime anyone
// wants a Question instance, give them this mock I just
// gave you.
$this->app->instance('Question', $this->questionMock);
// whatever...
}
}
Primitive Binding
Laravel's container provides a DSL for you to tell her how to resolve primitives as well. You say when BillingController class wants a $taxRate variable and it's not passed, give it 0.2. It's like setting default values from far far away!
app()->when('App\Http\Controllers\BillingController')
->needs('$taxRate')
->give(.2);
The use-case might be rare, but you might need them occasionally. This example might be a lil bit more sensual:
app()->when('App\Http\Controllers\CustomerController')
->needs('$customers')
->give(function() {
return Customer::paying();
});
Interface Binding
It's used when you want to bind interfaces to concrete implementations.
After reading a dozen articles on SOLID and how to be a better programmer, you decide to follow Dependency Inversion principle and instead of depending on concrete instances, you depend on abstractions.
After all, it's a good practice, in or out of Laravel.
class DatabaseWriter {
protected $db;
// Any concrete implementation of this interface will do
// Now, that I depend on this DatabaseAdapterInterface contract,
// I can work with MySQL, MongoDB and WhatevaDB! Awesome!
public function __construct(DatabaseAdapterInterface $db)
{
$this->db = $db;
}
public function write()
{
$this->db->query('...');
}
}
Without Laravel's container, you first need to create a concrete implementation of DatabaseAdapterInterface and pass it through DatabaseWriter's constructor to be able to instantiate it:
$dbWriter = new DatabaseWriter(new MongodbAdapter)
If MongodbAdapter has its own dependencies, you might end up here:
// Looks familiar, right?
// These are those recipes you used to give to Laravel container
// through simple binding.
$dbWriter = new DatabaseWriter(new MongodbAdapter(new MongodbConnection))
But with Laravel's container in the party, you tell her that when anyone asks for a concrete implementation of DatabaseAdapterInterface, ask no more and give them a MongodbAdapter:
app()->bind(DatabaseAdapterInterface::class, MongodbAdapter::class)
Then you go on and resolve an instance of DatabaseWriter out of container, like a boss:
$dbWriter = app()->make(DatabaseWriter::class)
Much easier and cleaner, right? You remove all the obvious clutter and move it to somewhere else. Your AppServiceProvider maybe.
OK, let's see how she works in this scenario. First, she probes DatabaseWriter for possible dependencies (through reflection), sees that it needs a DatabaseAdapterInterface. Checks her notebook, recalls that you told her that MongodbAdapter is the concrete implementation of that interface. Makes one and hand it over to DatabaseWriter.
You use these type of bindings almost all the time, if you're adhering to dependency inversion principle.
OK, enough with the chatter, let's see how she really works:
https://github.com/laravel/framework/blob/5.3/src/Illuminate/Container/Container.php#L627
I have some pattern that works great for me, but that I have some difficulty explaining to fellow programmers. I am looking for some justification or literature reference.
I personally work with PHP, but this would also be applicable to Java, Javascript, C++, and similar languages. Examples will be in PHP or Pseudocode, I hope you can live with this.
The idea is to use a lazy evaluation container for intermediate results, to avoid multiple computation of the same intermediate value.
"Dynamic programming":
http://en.wikipedia.org/wiki/Dynamic_programming
The dynamic programming approach seeks to solve each subproblem only once, thus reducing the number of computations: once the solution to a given subproblem has been computed, it is stored or "memo-ized": the next time the same solution is needed, it is simply looked up
Lazy evaluation container:
class LazyEvaluationContainer {
protected $values = array();
function get($key) {
if (isset($this->values[$key])) {
return $this->values[$key];
}
if (method_exists($this, $key)) {
return $this->values[$key] = $this->$key();
}
throw new Exception("Key $key not supported.");
}
protected function foo() {
// Make sure that bar() runs only once.
return $this->get('bar') + $this->get('bar');
}
protected function bar() {
.. // expensive computation.
}
}
Similar containers are used e.g. as dependency injection containers (DIC).
Details
I usually use some variation of this.
It is possible to have the actual data methods in a different object than the data computation methods?
It is possible to have computation methods with parameters, using a cache with a nested array?
In PHP it is possible to use magic methods (__get() or __call()) for the main retrieval method. In combination with "#property" in the class docblock, this allows type hints for each "virtual" property.
I often use method names like "get_someValue()", where "someValue" is the actual key, to distinguish from regular methods.
It is possible to distribute the data computation to more than one object, to get some kind of separation of concerns?
It is possible to pre-initialize some values?
EDIT: Questions
There is already a nice answer talking about a cute mechanic in Spring #Configuration classes.
To make this more useful and interesting, I extend/clarify the question a bit:
Is storing intermediate values from dynamic programming a legitimate use case for this?
What are the best practices to implement this in PHP? Is some of the stuff in "Details" bad and ugly?
If I understand you correctly, this is quite a standard procedure, although, as you rightly admit, associated with DI (or bootstrapping applications).
A concrete, canonical example would be any Spring #Configuration class with lazy bean definitions; I think it displays exactly the same behavior as you describe, although the actual code that accomplishes it is hidden from view (and generated behind the scenes). Actual Java code could be like this:
#Configuration
public class Whatever {
#Bean #Lazy
public OneThing createOneThing() {
return new OneThing();
}
#Bean #Lazy
public SomeOtherThing createSomeOtherThing() {
return new SomeOtherThing();
}
// here the magic begins:
#Bean #Lazy
public SomeThirdThing getSomeThirdThing() {
return new SomeThirdThing(this.createOneThing(), this.createOneThing(), this.createOneThing(), createSomeOtherThing());
}
}
Each method marked with #Bean #Lazy represents one "resource" that will be created once it is needed (and the method is called) and - no matter how many times it seems that the method is called - the object will only be created once (due to some magic that changes the actual code during loading). So even though it seems that in createOneThing() is called two times in createOneThing(), only one call will occur (and that's only after someone tries to call createSomeThirdThing() or calls getBean(SomeThirdThing.class) on ApplicationContext).
I think you cannot have a universal lazy evaluation container for everything.
Let's first discuss what you really have there. I don't think it's lazy evaluation. Lazy evaluation is defined as delaying an evaluation to the point where the value is really needed, and sharing an already evaluated value with further requests for that value.
The typical example that comes to my mind is a database connection. You'd prepare everything to be able to use that connection when it is needed, but only when there really is a database query needed, the connection is created, and then shared with subsequent queries.
The typical implementation would be to pass the connection string to the constructor, store it internally, and when there is a call to the query method, first the method to return the connection handle is called, which will create and save that handle with the connection string if it does not exist. Later calls to that object will reuse the existing connection.
Such a database object would qualify for lazy evaluating the database connection: It is only created when really needed, and it is then shared for every other query.
When I look at your implementation, it would not qualify for "evaluate only if really needed", it will only store the value that was once created. So it really is only some sort of cache.
It also does not really solve the problem of universally only evaluating the expensive computation once globally. If you have two instances, you will run the expensive function twice. But on the other hand, NOT evaluating it twice will introduce global state - which should be considered a bad thing unless explicitly declared. Usually it would make code very hard to test properly. Personally I'd avoid that.
It is possible to have the actual data methods in a different object than the data computation methods?
If you have a look at how the Zend Framework offers the cache pattern (\Zend\Cache\Pattern\{Callback,Class,Object}Cache), you'd see that the real working class is getting a decorator wrapped around it. All the internal stuff of getting the values stored and read them back is handled internally, from the outside you'd call your methods just like before.
The downside is that you do not have an object of the type of the original class. So if you use type hinting, you cannot pass a decorated caching object instead of the original object. The solution is to implement an interface. The original class implements it with the real functions, and then you create another class that extends the cache decorator and implements the interface as well. This object will pass the type hinting checks, but you are forced to manually implement all interface methods, which do nothing more than pass the call to the internal magic function that would otherwise intercept them.
interface Foo
{
public function foo();
}
class FooExpensive implements Foo
{
public function foo()
{
sleep(100);
return "bar";
}
}
class FooCached extends \Zend\Cache\Pattern\ObjectPattern implements Foo
{
public function foo()
{
//internally uses instance of FooExpensive to calculate once
$args = func_get_args();
return $this->call(__FUNCTION__, $args);
}
}
I have found it impossible in PHP to implement a cache without at least these two classes and one interface (but on the other hand, implementing against an interface is a good thing, it shouldn't bother you). You cannot simply use the native cache object directly.
It is possible to have computation methods with parameters, using a cache with a nested array?
Parameters are working in the above implementation, and they are used in the internal generation of a cache key. You should probably have a look at the \Zend\Cache\Pattern\CallbackCache::generateCallbackKey method.
In PHP it is possible to use magic methods (__get() or __call()) for the main retrieval method. In combination with "#property" in the class docblock, this allows type hints for each "virtual" property.
Magic methods are evil. A documentation block should be considered outdated, as it is no real working code. While I found it acceptable to use magic getter and setter in a really easy-to-understand value object code, which would allow to store any value in any property just like stdClass, I do recommend to be very careful with __call.
I often use method names like "get_someValue()", where "someValue" is the actual key, to distinguish from regular methods.
I would consider this a violation of PSR-1: "4.3. Methods: Method names MUST be declared in camelCase()." And is there a reason to mark these methods as something special? Are they special at all? The do return the value, don't they?
It is possible to distribute the data computation to more than one object, to get some kind of separation of concerns?
If you cache a complex construction of objects, this is completely possible.
It is possible to pre-initialize some values?
This should not be the concern of a cache, but of the implementation itself. What is the point in NOT executing an expensive computation, but to return a preset value? If that is a real use case (like instantly return NULL if a parameter is outside of the defined range), it must be part of the implementation itself. You should not rely on an additional layer around the object to return a value in such cases.
Is storing intermediate values from dynamic programming a legitimate use case for this?
Do you have a dynamic programming problem? There is this sentence on the Wikipedia page you linked:
There are two key attributes that a problem must have in order for dynamic programming to be applicable: optimal substructure and overlapping subproblems. If a problem can be solved by combining optimal solutions to non-overlapping subproblems, the strategy is called "divide and conquer" instead.
I think that there are already existing patterns that seem to solve the lazy evaluation part of your example: Singleton, ServiceLocator, Factory. (I'm not promoting singletons here!)
There also is the concept of "promises": Objects are returned that promise to return the real value later if asked, but as long as the value isn't needed right now, would act as the values replacement that could be passed along instead. You might want to read this blog posting: http://blog.ircmaxell.com/2013/01/promise-for-clean-code.html
What are the best practices to implement this in PHP? Is some of the stuff in "Details" bad and ugly?
You used an example that probably comes close to the Fibonacci example. The aspect I don't like about that example is that you use a single instance to collect all values. In a way, you are aggregating global state here - which probably is what this whole concept is about. But global state is evil, and I don't like that extra layer. And you haven't really solved the problem of parameters enough.
I wonder why there are really two calls to bar() inside foo()? The more obvious method would be to duplicate the result directly in foo(), and then "add" it.
All in all, I'm not too impressed until now. I cannot anticipate a real use case for such a general purpose solution on this simple level. I do like IDE auto suggest support, and I do not like duck-typing (passing an object that only simulates being compatible, but without being able to ensure the instance).
I have a follow-up question to the one discussed here:
Laravel core method confusion
I am in the same situation as driechel (author of question above) has been before, currently getting used to Laravel 4 FW and examining the core. Although a precise answer has been given I still don't understand the logic and what is happening under the hood. So I would very much appreciate a further explanation.
I know this might be a duplicate but since I cannot post comments yet I'll give it a shot with a new question. Hope it' ok this way.
I have been looking at this from another angle starting at this article:
http://blog.joynag.net/2013/05/facades-in-laravel-4-and-static-methods-resolution/
When examining the call File:get() I finally end up at the Container class' share function which is called with this actual parameter share(function() { return new Filesystem; }.
What I just can't figure out is the use of $container. Especially at the second occurence within the closure:
$object = $closure($container);
Could you please clarify this again? Why is $container passed as a parameter here and what is actually contained in it? As far as I understand $closure at that point holds and executes function() { return new Filesystem; } which has no input parameter.
I am lost. Studied this and the PHP anonymous functions/closures now for two days straight and still can't figure it out. I neither understand the syntax of $closure($container) here nor the logic.
For reference, this is the share method # v4.0.5.
So, what's happening here. I'll explain it in a couple of steps.
Calling The Share Method
As you pointed out this method is called from service providers. So, the FilesystemServiceProvider calls this method which looks something like this:
$this->app['files'] = $this->app->share(function() { return new Filesystem; });
It's assigning the return value of this share method to a binding in the container. In a nutshell, that return value will be the new Filesystem instance that is returned in the closure.
So What Does Share Do?
The share method is just another way of defining a singleton in IoC container. All this can be a bit intimidating at first. Basically, Laravel itself is an IoC container. All the classes are bound as instances on the container. Sometimes these instances should be the same instance on every call.
If you take a look at the referencing method above on GitHub, you'll notice that inside the closure a static variable is defined. It then checks if that variable is null, and if it is it resolves the closure (this is the closure that returns our new Filesystem instance). Then it simply returns the variable.
Now, the next time you use File::get() it doesn't need to instantiate the Filesystem class again, because it's already been instantiated and stored in the static $object variable. So it simply returns the same object to you.
So! Really, you could replace the $this->app['files'] line with this, and it would still work.
$this->app->instance('files', new Filesystem);
99% of services actually use the share method though because working inside a closure allows objects to be instantiated with more complex dependencies.
Hope this helps.
Code to be tested:
// Add the activation provider argument to the factory definition
$factoryDefinition = $container->getDefinition('gremo_subscription_factory');
$factoryDefinition->addArgument(new Reference($providerId));
Test method should check the addArgument method, including $providerId argument. I'm just learining PHPUnit and right now I'm only able to call $this->anything():
$container->expects($this->at(3))
->method('getDefinition')
->with('gremo_subscription_factory')
->will($this->returnValue($factory));
$factory->expects($this->once())
->method('addArgument')
->with($this->anything());
$this->pass->process($container);
How can I check that argument type is Reference class, and (in turn) its argument is exactly the string $providerId?
This is pretty complicated, especially since the Reference class is not dependency injected and method call doesn't return anything. However, I think you can get around it using argument constraints. Here's how I would do that second clause:
$factory->expects($this->once())
->method('addArgument')
->with($this->logicalAnd(
$this->isInstanceOf('Reference'),
$this->attributeEqualTo('attribute', $providerId)
));
The second item in the logicalAnd() is basically just checking the Reference object that is created to see if $providerId gets assigned correctly (I'm not sure what happens to $providerId in the Reference constructor, but I'm assuming it gets saved to an instance variable or something).
This sort of thing, however, is moving into the territory of testing implementation details of the Reference class, so tests like this are not great for maintaining SRP. All of this would be better solved by refactoring your code. Generally speaking, if it's hard to test, it is probably not the test suite's fault. If you are able to, consider changing things on that end first, rather than writing overly-clever tests.