Reputation: 2354
I am developing a package for Laravel 5, and now I need to benefit from dependency injection to have a more scalable and relaible application, I don't know which approach is the best to take and why, this is a piece of my code and I need to injected the Lang
class dependency
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');
}
}
In this link http://laravel.com/docs/4.2/ioc 2 approaches are suggested, Basic Usage
and Automatic Resolution
based on my understanding from the link
taking the first approach I need to add
App::bind('lang', function($app)
{
return new \Lang();
});
to the register part of application and then in the function I'll have something like this :
public function myFunction()
{
$lang = \App::make('lang');
$this->text = $lang::get('package::all.text1');
}
The other way is to modify the constructor
like
public function __construct(Lang $lang)
{
$this->lang = $lang;
}
And then instantiate object from Class like
$myController = App::make('MyController');
Which way is the better way to take for, considering that this class
is a Controller
and it will be called in the routes
file, or please correct me if my understanding from the link is not right. please also inform me why you suggest any of those approaches.
Upvotes: 7
Views: 4440
Reputation: 14232
It should be noted that using local IoC resolution ($app->make()
stylee) is not much better than using the facades directly (Lang::get()
stylee) - you're still very much relying on Laravel's specific classes without really making your code explicitly state that it needs these exact classes. So the general advice is to, as much as possible, code to an interface if you want your code to be as portable as possible.
Of course there are a couple of big downsides to this currently in PHP development:
LoggerInterface
interface) so you still have to rely on a particular instance of the interface (in this case, Laravel's).But anyway, here are my thoughts on your specific question. First off I should say that I haven't actually used Laravel 5 yet (just the 4s), but I have generally followed its development.
If the class I am coding will use a given dependency quite a lot or as a core part of how the class works I will use constructor dependency injection. Examples here are the Request or some Repository class in a controller, or a business logic class in a console command class.
If what I need I only need for a specific purpose (maybe redirecting from a controller and needing to generate a URI) I will resolve a local version from the IoC container ($this->app->make()
) and then use that. If I were using Laravel 5 and the method was called by Laravel directly (e.g. a controller's action method) I may use method injection for this, I'm not 100% sure.
As a final note, the general advice is that if your constructor method signatures get too big due to a lot of dependencies:
$class->setRequest()
method. The downside of doing this is that you need to tell Laravel's IoC container how to instantiate your object (i.e. that these setters must be called). It's not that big a deal but something worth noting.Relevant links:
Upvotes: 7