Laravel Service Container and Service Provider - laravel

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

Related

Laravel ServiceProvider vs. Middleware

I've got a question regarding Laravel. Where is the difference in using ServiceProviders or Middleware in Laravel?
So I mean, when do I use ServiceProviders and when should I choose a Middleware?
Both are executed on every request, don't they? Maybe someone of you have examples for use-cases.
There is a big difference between ServiceProviders and Middleware.
Service providers are the central place of all Laravel application bootstrapping. This can include your own application, as well as all of Laravel's core services. This is all bootstrapped via service providers. By bootstraping, I mean registering things, including registering service container bindings, event listeners, middleware, and even routes. Service providers are the central place to configure your application. So, in short, Service providers are used to tell Laravel which classes and files should be loaded and used when you run your application. Service providers have two methods: register() and boot().
Within the register method, you should only bind things into the service container. You should never attempt to register any event listeners, routes, or any other piece of functionality within the register method. Simple example would be registering your custom class:
public function register()
{
$this->app->bind('App\Library\Services\CustomClass ', function ($app) {
return new CustomClass ();
});
}
We've imported App\Library\Services\CustomClass so that we can use it. In the register method, we've used the bind method of the service container to add our service container binding. So, whenever the App\Library\Services\CustomClass dependency needs to be resolved, it'll call the closure function, and it instantiates and returns the App\Library\Services\CustomClass object.
The boot method is called after all other service providers have been registered, meaning you have access to all other services that have been registered by the framework. In most cases, you want to register your event listeners in this method, which will be triggered when something happens, and so on.. One simple example could be extending Laravel's validation to add some custom fields of your own:
public function boot()
{
Validator::extend('my_custom_validator', function ($attribute, $value, $parameters, $validator) {
// validation logic goes here...
}
More info about Service providers could be found on official documentation.
On the other side, middleware provides a convenient mechanism for filtering HTTP requests entering your application. For example, Laravel includes a middleware that verifies the user of your application is authenticated. If the user is not authenticated, the middleware will redirect the user to the login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application:
public function handle($request, Closure $next)
{
if (Auth::check()) {
// The user is logged in, do something...
}else{
// The user is not logged in, do something else...
}
More info about middleware could be found in official documentation.

Autowired not working with Azure function

I am quit new in Azure function.
I found it as a interesting topic.right now,I have already develped azure function and works fine.
BUT my story will not end here. In the Function Method, I am trying to Autowiring my Repository class in spring in order to access to my DB layer.
but it gives me a null pointer exception. means that , "#Autowired" annotation is not working and not initiate my HotelController Class.
Any Idea , why I am not able to get the instance in Azure function?
I think you should take a look at:
spring-cloud-function-adapter-azure
This project provides an adapter layer for a Spring Cloud Function application onto Azure. You can write an app with a single #Bean of type Function and it will be deployable in Azure if you get the JAR file laid out right.
There is an AzureSpringBootRequestHandler which you must extend, and provide the input and output types as annotated method parameters (enabling Azure to inspect the class and create JSON bindings). The base class has two useful methods (handleRequest and handleOutput) to which you can delegate the actual function call, so mostly the function will only ever have one line.
And the sample that shows how to use it.
Hope it helps!

Laravel 5.1 defer service provider until another is loaded

I'm using the FormBuilder in Laravel 5.1. The HtmlServiceProvider states the Html and Form facades should defer loading until they are actually needed, which is fine.
However, I have created a FormServiceProvider which registers several macros that I will use in my views. This provider doesn't run any bindings, it simply records a few macros within the FormBuilder class.
However, by storing these macros using the boot method on my own service provider, it's loading the Form binding instantly (making the deferred loading pointless).
Question
Is there any way to defer the boot method in one service provider until another service provider has binded facades?
OR, is there a way to listen for specific binding (or aliasing) events, then manually run a service provider?
you can listen when container resolves object of any type or when container resolves objects of type XXX as below,
$this->app->resolving(function ($object, $app) {
// Called when container resolves object of any type...
});
$this->app->resolving(FooBar::class, function (FooBar $fooBar, $app) {
// Called when container resolves objects of type "FooBar"...
});
here is the DOC
You should refer here.
your service provider should provide Form:class and Html::class.

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.

How to enable Dependency Injection for ServiceRoute in MVC3 and WCF Web API

I am creating a MVC3 website that will expose a REST API using WCF Web API.
To register routes to the REST API I add code to the Global.asax similar to the code below.
routes.MapServiceRoute<RelationsService>("relations");
This works well enough but i need to use a DI approach to inject the dependencies that the Service depends on.
As you can see in the code above the MVC framework is creating the instance of the RelationsService but this should be done by the DI container.
Does anyone know how to configure MVC3 so that my own DI container is used for creating the instances of the Services?
You have to extend your current service registration call with an IHttpHostConfigurationBuilder that has been created with an IResourceFactory.
var configurationBuilder = HttpHostConfiguration.Create()
.SetResourceFactory(new ResourceFactory());
routes.MapServiceRoute<RelationsService>("relations", configurationBuilder);
Then if you for instance use StructureMap as preferred IoC/DI tool you can just ask for the service in the GetInstance method.
public class ResourceFactory : IResourceFactory
{
public object GetInstance(Type serviceType, InstanceContext instanceContext, HttpRequestMessage request)
{
return ObjectFactory.GetInstance(serviceType);
}
}

Resources