register serviceprovider at runtime instead of app.php - laravel

Is it possible to register serviceprovider at runtime instead of having it preregistered in app.php providers list? If yes how would it be done? Could I register it from some other service provider that is aready in app.php and running?

its possible to register a service provider at any time by calling the register method on the ioc container...
Using the facade:
App::register($yourProvider);
Using the helper:
app()->register($yourProvider);

Related

Class translator does not exist when using app()->setLocale() in app service provider

I'm trying to use localization in my Laravel 5.8 application. Following up with this How To Build An Efficient and SEO Friendly Multilingual Architecture For Your Laravel Application I have always do the same steps and have no problems. However, when I try it with Laravel 5.8 I keep getting Class translator does not exist from app()->setLocale(request()->segment(1)); I use that in the app service provider for some reason.
AppServiceProvider
<!-- language: php -->
public function register()
{
app()->setLocale(request()->segment(1));
Schema::defaultStringLength(191);
}
The register method is not to be used for using services.
Try adding your code in the boot method of the class.
Also I believe a better place for adding this is in a middleware then in the service provider.

Laravel Service Container and Service Provider

Need to understand Laravel service container and service provider through an example.
Hello and welcome to stackoverflow!
Service container is the place our application bindings are stored. And the service providers are the classes where we register our bindings to service container. In older releases of Laravel, we didn't have these providers and people were always asking where to put the bindings. And the answer was confusing. "Where it makes the most sense."! Then, Laravel introduced these service providers and Providers directory to clear things up for people.
To make it easy to understand, I will include a basic example:
interface AcmeInterface {
public function sayHi();
}
class AcmeImplementation implements AcmeInterface {
public function sayHi() {
echo 'Hi!';
}
}
// Service Container
$app = new \Illuminate\Database\Container;
// Some required stuff that are also service providing lines
// for app config and app itself.
$app->singleton('app', 'Illuminate\Container\Container');
$app->singleton('config', 'Illuminate\Config\Repository');
// Our Example Service Provider
$app->bind(AcmeInterface::class, AcmeImplementation::class);
// Example Usage:
$implementation = $app->make(AcmeInterface::class);
$implementation->sayHi();
As you see;
First we create the container (In real life, Laravel does this for us inside bootstrap/app.php),
Then we register our service (inside our Service Provider classes, and config/app.php),
and finally, we get and use our registered service. (inside controllers, models, services..)
Service container is where your services are registered.
Service providers provide services by adding them to the container.
By reference of Laracast. Watch out to get understand.
Service container: https://laracasts.com/series/laravel-from-scratch-2017/episodes/24
Service providers: https://laracasts.com/series/laravel-from-scratch-2017/episodes/25

Confused - AppServiceProvider.php versus app.php

Where do I specify my bindings exactly? It seems I can do it in either of these files.
config/app.php
Inside of 'providers' =>
app/Providers/AppServiceProvider.php
Inside of register()
The service providers array is loaded via config/app.php. This is the only actual place that providers are registered, and is where you should put Service Providers.
AppServiceProvider is for Laravel-specific services that you've overridden (or actually specified), such as the Illuminate\Contracts\Auth\Registrar, The HTTP/Console Kernels, and anything you wish to override in Laravel. This is a single service provider, that registers container bindings that you specify.
Really, you could load anything you want here, but there's a bunch of ready-to-go service providers in the app/Providers directory for you so you don't have to go and make one yourself.
If your bindings are not related to App, then I would create a new ServiceProvider class where I overwrite the register method with my new binding, then you have to let Laravel know that this class exists registering as a Provider in your config/app.php providers list, that is:
app/Providers/MyNewClassServiceProvider.php
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class MyNewClassServiceProvider extends ServiceProvider {
public function register()
{
$this->app->bind(
'App\Repository\MyNewClassInterface',
'App\Repository\MyNewClassRepository'
);
}
}
config/app.php
'providers' => [
// Other Service Providers
'App\Providers\MyNewClassServiceProvider',
],

Laravel 5 binding other object to contracts

I started using Laravel 5 and tried to learn things about contracts but i still have some questions about them.
For example I want to alter the Illuminate\Contracts\Auth\PasswordBroker contract (used in App\Http\Controllers\Auth\PasswordController )
The contract is an Interface but somehow Laravel knows what implementation belongs to that contract..
I want to change the implementation to my custom one.
But what is the correct way of loading my custom PasswordBroker class?
Should i bind my custom class in the AppServiceProvider?
$this->app->bind(
'Illuminate\Contracts\Auth\PasswordBroker',
'App\Services\MyPasswordBroker'
);
Where does Laravel itself bind the default implementations?
It's in 'Illuminate/Foundation/Application.php'
'auth.password' => ['Illuminate\Auth\Passwords\PasswordBroker', 'Illuminate\Contracts\Auth\PasswordBroker'],
Can I just overwrite the default bindings?
According to the official documentations: Yes.
You can easily extend and override this class within your own application by overriding this binding.
But remember to replace the original service provider in the config/app.php
Note that this class extends the HashServiceProvider, not the default ServiceProvider base class. Once you have extended the service provider, swap out the HashServiceProvider in your config/app.php configuration file with the name of your extended provider.
Your case
So, in your case, you need to extend the 'Illuminate\Auth\Passwords\PasswordResetServiceProvider' to remain other things happened in the service provider.
Take a look at the default service provider.
Let me know if you have other questions.

Laravel 4 - when to use service providers?

I tried to google it but did not find detailed information.
Service providers are a great way to group related IoC registrations
in a single location. Think of them as a way to bootstrap components
in your application.
Not understanding from the documentation. Is this only needed when I create packages? So when I am regular developer and not making some packages to release in public - I don't need to care?
One of the keys to building a well architected Laravel application is
learning to use serviceproviders as an organizational tool. When you are
registering many classes with the IoC container, all of those bindings
can start to clutter your app/start files. Instead of doing container
registrations in those files, create serviceproviders that register
related services.
So, this is a way to organize your application's services in one place to keep it more organized. A service provider must have at least one method: register. The register method is where the provider binds classes to the container. When a request enters your application and the framework is booting up, the register method is called on the providers listed in your configuration file
'providers' => array(
'Illuminate\Foundation\Providers\ArtisanServiceProvider',
'Illuminate\Auth\AuthServiceProvider',
'Illuminate\Cache\CacheServiceProvider',
// more ...
'Illuminate\Html\HtmlServiceProvider',
// more ...
)
This is providers array in app.php config file and this is the HtmlServiceProvider stored in 'Illuminate\Html\HtmlServiceProvider.php'
use Illuminate\Support\ServiceProvider;
class HtmlServiceProvider extends ServiceProvider {
//...
public function register()
{
$this->registerHtmlBuilder();
$this->registerFormBuilder();
}
protected function registerHtmlBuilder()
{
$this->app['html'] = $this->app->share(function($app)
{
return new HtmlBuilder($app['url']);
});
}
protected function registerFormBuilder()
{
$this->app['form'] = $this->app->share(function($app)
{
$form = new FormBuilder($app['html'], $app['url'], $app['session']->getToken());
return $form->setSessionStore($app['session']);
});
}
}
When, Laravel boots up, it calls this (register) method and in this method there are two lines, these line calls two methods, registerHtmlBuilder() and registerFormBuilder(), these both methods components to the IoC container using
$this->app['html'] = $this->app->share(...);
$this->app['form'] = $this->app->share(...);
In this case both are anonymous functions which returns an instance of html/form class and that's why, when you use
Html::link(...);
Or, using form
Form::input(...);
You get the bound class from the $app object which is available to your application. In this case 'Html' => 'Illuminate\Support\Facades\Html', is used to alias the main class in the aliases array in the app.php file.
So, in Laravel, service providers are a way to organize things in a nice cleaner way, during the boot up process of your application, Laravel runs all register methods from all the service providers so each component become available (bound) to the IoC container so you can access them in your application.
It's worth mentioning that, after calling of all register methods from service providers all the boot methods from those service providers get called. In that case, if you need to use any service from the application (IoC/Service Container) within the service provider class then you should use that service from the boot method since it's not guranteed that any service is avaiable during the registeration of service providers (within register method) because services are registered through register method of each service provider but within the boot method you may use any service because by then every service is hopefully registered.
Check this answer Laravel 4 : How are Facades resolved? too, it may help you to understand.
There's nothing a service provider can do that you can't just slap into app/start/global.php, but with a service provider you gather all the logic in one place and can develop application in a more modular fashion.
If you're making a package a service provider is pretty much a must.
In Laravel, service providers are directly related to the way in which IoC container works. They allow easier and more modular approach to dependencies. In fact, it is a great pattern for organizing your code in a bootstrap fashion ( even outside of Laravel ). I think If you are regular developer you still need to know the basics of Laravel service providers, because that pattern is integral part of Laravel architecture. I am sure it can make your work easier.
For example, when installing a package, your have to give application access to that package - one of the best solution is through service providers list and a facade. On the other hand, I can't imagine being a Laravel developer without knowing basics of SP-s.

Resources